Подтвердить что ты не робот

Сравнение изображений растровых изображений в Android

Есть ли способ проверить, являются ли растровые изображения одинаковыми? может кто-нибудь помочь мне?

4b9b3361

Ответ 1

В зависимости от того, как вы определяете то же самое. Если вы имеете в виду точный файл, вы можете сделать md5sum файлов. Это будет то же самое для всех типов файлов, которые я предполагаю.

Поскольку вы специально различаете файлы растровых изображений, вас могут заинтересовать файлы, которые отличаются по размеру. Это немного сложнее. Если они имеют одинаковый размер, но не совсем одинаковый (но очень похожий на друг друга), вы можете сравнить каждый отдельный пиксель, и если достаточно пикселей (порог 1) достаточно близко друг к другу в цвете (порог 2), вы можете объявить они как одно и то же.

Вы можете getPixel(int,int) получить цвет, см. эту страницу

Ответ 3

Это должно быть примерно так:

public boolean equals(Bitmap bitmap1, Bitmap bitmap2) {
    ByteBuffer buffer1 = ByteBuffer.allocate(bitmap1.getHeight() * bitmap1.getRowBytes());
    bitmap1.copyPixelsToBuffer(buffer1);

    ByteBuffer buffer2 = ByteBuffer.allocate(bitmap2.getHeight() * bitmap2.getRowBytes());
    bitmap2.copyPixelsToBuffer(buffer2);

    return Arrays.equals(buffer1.array(), buffer2.array());
}

Ответ 4

Этот вопрос кажется старым, но я потратил некоторое время на этот вопрос сегодня, и вот что я сделал.

private static boolean compare(Bitmap b1, Bitmap b2) {
    if (b1.getWidth() == b2.getWidth() && b1.getHeight() == b2.getHeight()) {
        int[] pixels1 = new int[b1.getWidth() * b1.getHeight()];
        int[] pixels2 = new int[b2.getWidth() * b2.getHeight()];
        b1.getPixels(pixels1, 0, b1.getWidth(), 0, 0, b1.getWidth(), b1.getHeight());
        b2.getPixels(pixels2, 0, b2.getWidth(), 0, 0, b2.getWidth(), b2.getHeight());
        if (Arrays.equals(pixels1, pixels2)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

Ответ 5

Основная проблема для API менее 12 заключается в том, что мы получаем ошибку OutOfMemory для больших разрешений файлов. Я решил это, разделив растровые изображения на части (10 в примере), а затем сравнив их по байтам:

private boolean compareBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    if (Build.VERSION.SDK_INT > 11)
    {
        return bitmap1.sameAs(bitmap2);
    }

    int chunkNumbers = 10;
    int rows, cols;
    int chunkHeight, chunkWidth;
    rows = cols = (int) Math.sqrt(chunkNumbers);
    chunkHeight = bitmap1.getHeight() / rows;
    chunkWidth = bitmap1.getWidth() / cols;

    int yCoord = 0;
    for (int x = 0; x < rows; x++)
    {
        int xCoord = 0;
        for (int y = 0; y < cols; y++)
        {
            try
            {
                Bitmap bitmapChunk1 = Bitmap.createBitmap(bitmap1, xCoord, yCoord, chunkWidth, chunkHeight);
                Bitmap bitmapChunk2 = Bitmap.createBitmap(bitmap2, xCoord, yCoord, chunkWidth, chunkHeight);

                if (!sameAs(bitmapChunk1, bitmapChunk2))
                {
                    recycleBitmaps(bitmapChunk1, bitmapChunk2);
                    return false;
                }

                recycleBitmaps(bitmapChunk1, bitmapChunk2);

                xCoord += chunkWidth;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        yCoord += chunkHeight;
    }

    return true;
}

private boolean sameAs(Bitmap bitmap1, Bitmap bitmap2)
{
    // Different types of image
    if (bitmap1.getConfig() != bitmap2.getConfig())
        return false;

    // Different sizes 
    if (bitmap1.getWidth() != bitmap2.getWidth())
        return false;

    if (bitmap1.getHeight() != bitmap2.getHeight())
        return false;

    int w = bitmap1.getWidth();
    int h = bitmap1.getHeight();

    int[] argbA = new int[w * h];
    int[] argbB = new int[w * h];

    bitmap1.getPixels(argbA, 0, w, 0, 0, w, h);
    bitmap2.getPixels(argbB, 0, w, 0, 0, w, h);

    // Alpha channel special check 
    if (bitmap1.getConfig() == Bitmap.Config.ALPHA_8)
    {
        final int length = w * h;
        for (int i = 0; i < length; i++)
        {
            if ((argbA[i] & 0xFF000000) != (argbB[i] & 0xFF000000))
            {
                return false;
            }
        }
        return true;
    }

    return Arrays.equals(argbA, argbB);
}

private void recycleBitmaps(Bitmap bitmap1, Bitmap bitmap2)
{
    bitmap1.recycle();
    bitmap2.recycle();
    bitmap1 = null;
    bitmap2 = null;
}