C#中从位图流计算MD5时出现问题

7
当我将Bmp作为流传递时,函数总是返回,
D4-1D-8C-D9-8F-00-B2-04-E9-80-09-98-EC-F8-42-7E

但是文件在磁盘上正确保存。当我从磁盘加载bpm时,函数返回正确的MD5。使用不同值传递“new Bitmap(int x, int y);”也会返回相同的MD5。

为什么会发生这种情况?

    public static string GetMD5Hash()
    {

        Bitmap Bmp = new Bitmap(23, 46); // 
        using (Graphics gfx = Graphics.FromImage(Bmp))
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(32, 44, 2)))
        {
            gfx.FillRectangle(brush, 0, 0, 23, 46);
        }



        using (var md5 = MD5.Create())
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                Bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
 \//EDITED:     Bmp.Save(@"C:\Test\pizdanadysku.bmp"); // Here saving file on disk, im getting diffrent solid color

                return BitConverter.ToString(md5.ComputeHash(memoryStream)); //Always return D4-1D-8C-D9-8F-00-B2-04-E9-80-09-98-EC-F8-42-7E - I noticed that is MD5 of empty 1x1px Bmp file
            } 
        }
    }

有人能解释一下这种奇怪的行为吗?


你的代码中有两个完全不同的图像... 一个是 image,另一个是 Bmp - user253751
是的,应该使用“Bmp”而不是“image”,但问题出在流的位置上。@Michael Randall的回答解决了这个问题。 - Yszty
1
有趣的文件名选择。 - oleksii
1个回答

10

流操作往往会因各种原因(包括某些流只能读取,例如NetworkStream),而趋向于仅向前移动,因此保存图像很可能只是将流推进到结尾。

此外,一些有帮助的编辑人员指出了这一点(如@jpa)。

D4-1D-8C-D9-8F-00-B2-04-E9-80-09-98-EC-F8-42-7E

一个空字符串的经典MD5校验值。

我的直觉是你只需要重置流的位置就可以得到你想要的结果。

memoryStream.Seek(0, SeekOrigin.Begin)
// or 
memoryStream.Position = 0;

请问为什么不重置流的位置会导致OP的错误? - Jan Schultke
@jpa 感谢您的编辑,我很惊讶这个问题引起了这么多关注。我已经进行了更新并加以说明。 - TheGeneral

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