我无法找到答案,因此希望有人能帮助我。我正在尝试使用以下代码来序列化和反序列化图像。单元测试图像序列化
public override string Serialize(Image image)
{
ImageFormat format = ImageFormat.Png;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
public override Image Deserialize(string value)
{
if (string.IsNullOrWhiteSpace(value))
throw new Exception("Invalid serialized string. Unable to deserialize image");
byte[] imageBytes = Convert.FromBase64String(value);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
Image image = Image.FromStream(ms);
return image;
}
}
从视觉测试此代码按预期工作,但我无法通过单元测试来验证这一点。我试图使用下面的代码来比较图像,如果图像是相同的,我已经能够成功地进行单元测试。
public static bool IsEqualTo(this Image sourceImage, Image compareImage)
{
if (sourceImage.Size != compareImage.Size)
return false;
byte[] sourceHash = sourceImage.CreateHash();
byte[] compareHash = compareImage.CreateHash();
return sourceHash.IsEqualTo(compareHash);
}
private static byte[] CreateHash(this Image image)
{
ImageConverter converter = new ImageConverter();
byte[] byteArray = (byte[])converter.ConvertTo(image, typeof(byte[]));
SHA256Managed shaM = new SHA256Managed();
byte[] hash = shaM.ComputeHash(byteArray);
return hash;
}
private static bool IsEqualTo(this byte[] source, byte[] compare)
{
if (source.Length != compare.Length)
return false;
for (int i = 0; i < source.Length; i++)
if (source[i] != compare[i])
return false;
return true;
}
与这两个部分的完成我试图写一个单元测试,假设系列化成功发生,并且将简单地验证我继续得到同样的序列化的字符串。然后序列化的字符串用于初始化,我比较使用下面的代码的新形象:
[Fact]
public void Deserialize_Success()
{
Image expected = this.LoadImage();
string imageString = this.GetImageString();
ImageSerializer serializer = new ImageSerializer();
Image actual = serializer.Deserialize(imageString);
bool match = expected.IsEqualTo(actual);
Assert.True(match);
}
如果我将图像保存到文件系统,并进行直观比较,它看起来像一切都按我本来期望但单元测试将失败。我能想到的唯一情况是,由于用于加载图像的方法导致图像显示不同,导致出现小的变化。
任何人都可以阐明我如何能够成功地为此编写单元测试?
更新:
我发现这个问题Weird behavior during Image byte array serialization这是相似的。我试图使用从http://en.wikipedia.org/wiki/File:Snow_flake_icon.png使用的相同图像,但即使如此,我也看到了差异。在我指导下使用这个问题时,我仔细研究了正在创建的字节数组。
第一个主要区别是,在反序列化的图像中,我们前十三个字节不存在。还有额外的29个字节的差异,所有的差异都在前46个字节。我的问题是,我认为我不认为总是会有13个字节的偏移量用于反序列化的图像,并且我可以忽略前46个字节。
全部细节是:
Expected Length: 17932 Actual Length: 17919
expected[0]=137 Actual Not Present
expected[1]=80 Actual Not Present
expected[2]=78 Actual Not Present
expected[3]=71 Actual Not Present
expected[4]=13 Actual Not Present
expected[5]=10 Actual Not Present
expected[6]=26 Actual Not Present
expected[7]=10 Actual Not Present
expected[8]=0 Actual Not Present
expected[9]=0 Actual Not Present
expected[10]=0 Actual Not Present
expected[11]=13 Actual Not Present
expected[12]=73 Actual Not Present
expected[13]=72 actual[13]=72
expected[14]=68 actual[14]=68
expected[15]=82 actual[15]=82
expected[16]=0 actual[16]=0
expected[17]=0 actual[17]=0
expected[18]=1 actual[18]=1
expected[19]=0 actual[19]=0
expected[20]=0 actual[20]=0
expected[22]=1 actual[22]=1
expected[24]=8 actual[24]=8
expected[25]=6 actual[25]=6
expected[26]=0 actual[26]=0
expected[27]=0 actual[27]=0
expected[28]=0 actual[28]=0
expected[29]=92 actual[29]=92
expected[30]=114 actual[30]=114
expected[31]=168 actual[31]=168
expected[32]=102 actual[32]=102
expected[35]=0 actual[35]=0
expected[36]=1 actual[36]=4
expected[37]=115 actual[37]=103
expected[38]=82 actual[38]=65
expected[39]=71 actual[39]=77
expected[40]=66 actual[40]=65
expected[42]=174 actual[42]=0
expected[43]=206 actual[43]=177
expected[44]=28 actual[44]=143
expected[45]=233 actual[45]=11
这些缺失字节的前8个是PNG头,其余5个可能也是图像头的一部分。我认为ImageConverter的使用看起来很可疑。难道你不能将图像保存到内存流中以从中获取字节数据吗? –
@AndersForsgren ImageConverter仅用于创建散列以确定图像是否匹配而不是用于序列化。字节比较使用源图像的实际字节和使用MemoryStream的反序列化图像进行。 – kmcbrearty