Сравнение файлов BMP? - PullRequest
3 голосов
/ 16 марта 2009

Я хочу сравнить два bmp файла. Я думал о двух подходах:

  1. для сравнения заголовка, а также информационного заголовка двух файлов
  2. преобразовать файл bmp в двоичный файл и затем выполнить приведенное выше сравнение

Но я не знаю, с чего начать, и какой подход будет лучше. Буду рад, если кто-нибудь сможет мне помочь!

Ответы [ 5 ]

1 голос
/ 16 марта 2009

Я не знаю, на какой платформе вы хотите это реализовать, но вот некоторые фрагменты кода, которые могут быть полезны:

Сравните два изображения с C #

Это фрагмент для сравнения 2 изображений чтобы увидеть, если они одинаковы. это Метод сначала преобразует каждый битмап в байтовый массив, затем получает хэш каждого массив. Затем мы перебираем каждый хеш, чтобы увидеть, совпадают ли они.

/// <summary>
/// method for comparing 2 images to see if they are the same. First
/// we convert both images to a byte array, we then get their hash (their
/// hash should match if the images are the same), we then loop through
/// each item in the hash comparing with the 2nd Bitmap
/// </summary>
/// <param name="bmp1"></param>
/// <param name="bmp2"></param>
/// <returns></returns>
public bool doImagesMatch(ref Bitmap bmp1, ref Bitmap bmp2)
{
  ...
}
0 голосов
/ 11 мая 2009

Вышеуказанные решения не работали для меня, когда у меня было два изображения, которые различались только по глубине цвета - одно было 32 бита на дюйм, а другое 8 бита на дюйм. Решение, к которому я пришел, использовало LockBits для преобразования всех изображений в 32bpp, Marshal.Copy (), чтобы получить данные в массив, а затем просто сравнить массивы.

/// <summary>
/// Compares two images for pixel equality
/// </summary>
/// <param name="fname1">first image file</param>
/// <param name="fname2">second image file</param>
/// <returns>true if images are identical</returns>
public static string PageCompare(string fname1, string fname2) {
    try {
        using (Bitmap bmp1 = new Bitmap(fname1))
        using (Bitmap bmp2 = new Bitmap(fname2)) {
            if (bmp1.Height != bmp2.Height || bmp1.Width != bmp2.Width)
                return false;

            // Convert image to int32 array with each int being one pixel
            int cnt = bmp1.Width * bmp1.Height * 4 / 4;
            BitmapData bmData1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height),
                ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            BitmapData bmData2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height),
                ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            Int32[] rgbValues1 = new Int32[cnt];
            Int32[] rgbValues2 = new Int32[cnt];

            // Copy the ARGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(bmData1.Scan0, rgbValues1, 0, cnt);
            System.Runtime.InteropServices.Marshal.Copy(bmData2.Scan0, rgbValues2, 0, cnt);

            bmp1.UnlockBits(bmData1);
            bmp2.UnlockBits(bmData2);
            for (int i = 0; i < cnt; ++i) {
                if (rgbValues1[i] != rgbValues2[i])
                    return false;
            }
        }
    }
    catch (Exception ex) {
        return false;
    }
    // We made it this far so the images must match
    return true;
}
0 голосов
/ 16 марта 2009

Что вы сравниваете? Вы хотите увидеть, если 2 изображения одинаковы? Или вам нужны степени разницы? Для точных совпадений, как насчет создания и сравнения хэшей обоих файлов?

0 голосов
/ 16 марта 2009

Вы можете использовать метод расширения в .NET 3.0+ для этого, чтобы предоставить метод сравнения для всех растровых изображений:

    public static bool Compare(this Bitmap bmp1, Bitmap bmp2)
    {
        //put your comparison logic here
    }
0 голосов
/ 16 марта 2009

Ну, у вас есть как минимум два варианта:

  • Изображения в основном одинаковые
    В этом случае я бы рекомендовал сравнить с использованием решения Сплаттне

  • Изображения обычно разные и только иногда совпадают
    В этом случае может случиться так, что вы можете отклонить любое сходство между двумя изображениями с помощью быстрого сравнения заголовка информации (подумайте «размер одинаковый?») И выполнить полное сравнение, только если информация неоднозначна размер это то же самое)

...