快速比较Base64编码的图像

3
我有一个逻辑需要比较base64编码的图像(JPEG和PNG)并检查它们是否相同。
最基本的方法是比较整个字符串。
由于图像往往非常大,我想知道是否有更快或更节省内存的比较方式。例如,仅比较前x个字符,但base64是按字节进行的,这只会比较图片的前x个字节。
我不熟悉jpeg和png格式的内部工作原理以及第一个字节碰撞(产生错误的正匹配)的机会,但如果它的可能性相当低(如1:10000),那就可以接受。
可以实现更好的比较吗?
可以实现低误报匹配率的更好比较吗?
基本比较非常缓慢,而且由于我需要将整个字符串读入内存以进行其他操作,因此我可能最终会在它们上使用简单的等式比较,我只是对其他可能性感兴趣。
抱歉没有明确说明,但这个问题并不是关于比较图像数据。有损图像格式使其仍然很痛苦,如果图像以不同的格式或不同的选项保存,则它是不同的。

1
我猜你的意思是将png与png进行比较,将jpeg与jpeg进行比较 - 逐像素比较png和jpeg永远不会匹配,因为jpeg是有损压缩的。如果你想找到完全相同的文件,比较字节(字符串)应该没问题,我认为。 - 500 - Internal Server Error
当然可以。相同意味着它们是一样的。 - vinczemarton
2
你只需要比较两张图片,还是需要将一张图片与数据库中存储的N张图片进行比较?在第二种情况下,你可以存储每张图片的哈希值。 - pmoleri
@pmoleri 通常会将来自源1的图像与来自源2的3-4个图像进行比较。由于我只能控制源2(即SQL数据库),因此可以存储例如MD5。但是,我需要为源1中的每个图像创建一个md5哈希值。好主意。 - vinczemarton
3个回答

2

如评论中所述,一张图片只会被比较几次(可能有3或4个匹配项)。

由于比较的次数很少,计算哈希/摘要的成本可能不太划算。

我建议进行直接字符串比较,如果匹配,则仅需要比较字符串长度,如果不匹配,则仅需处理几个字节,直到第一个差异为止。如果您想避免从数据库检索所有记录,则可以选择仅检索与要比较的字符串长度相同的记录。


2
注意: Base64编码的图像内部包含(经过Base64解码后)PNG或JPEG格式的编码图像。因此,如果您比较该内容(无论是否进行了Base64解码),只有在完整的PNG/JPEG流相等时才会匹配,就像比较文件一样。如果您想测试原始图像的相等性(即相同的像素),这种方法将不起作用。不仅是因为元数据(例如时间戳),而且因为两种格式都在其编码中具有额外的自由度(压缩算法和参数),因此相同的图像内容可以生成不同的PNG/JPEG图像。
如果您接受这一点,并且确实想要在(比如)文件级别上测试图像的相等性,那么您可以首先测试字符串长度(如果图像很大,则长度相等的概率不高),只有当它们匹配时才进行逐字节比较。(请参见pmoleri答案中有关哈希/摘要的内容。) 如果您想进行优化,请仅比较一部分(比如中间的100个字节)。特别是PNG图像具有所有相同的16个字节和最后12个字节。

1
尝试将这些特定格式转换为图像并使用此函数。我不知道在你的情况下是否有效,但请尝试并告诉我 :)
public bool CompareImages(Image img1, Image img2)
{
    bool rtn = true;

    ImageConverter converter = new ImageConverter();
    Bitmap bmp1 = img1;
    Bitmap bmp2 = img2;

    int dWid = Math.Min(bmp1.Width, bmp2.Width);
    int dHei = Math.Min(bmp1.Height, bmp2.Height);

    for (int x = 0; x <= dWid - 1; x++) {
        for (int y = 0; y <= dHei - 1; y++) {
            if (!bmp1.GetPixel(x, y).Equals(bmp2.GetPixel(x, y))) {
                rtn = false;
                break;
            }
        }
    }

    return rtn;
}

这对我来说似乎不太优化。转换为“Image”是一个更大的操作。 - vinczemarton
我这个方法虽然不是最好的解决方案,但可以比较图片。除非你要比较成千上万张大图,否则这个方法是可行的。 - Kennyomar
1
对不起,我的问题没有表达清楚,但这不是我需要的。无论如何,比较有损格式要比这更棘手一些。 - vinczemarton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接