C#.NET:将图标转换为byte[],再将其转换回来

17
如何在 .NET2 中简单地将 System.Drawing.Icon 类型和 byte[] 之间进行转换?请确保不改变原始含义。
3个回答

33

你可以通过一个 MemoryStream 来实现,基本上是这样的:

public static byte[] IconToBytes(Icon icon)
{
    using (MemoryStream ms = new MemoryStream())
    {
        icon.Save(ms);
        return ms.ToArray();
    }
}

public static Icon BytesToIcon(byte[] bytes)
{
    using (MemoryStream ms = new MemoryStream(bytes))
    {
        return new Icon(ms);
    }
}

(历史注:我曾不确定是否安全地处理传递给构造函数的流。例如,对于保留流并稍后从中读取的Bitmap,这样做是不安全的...但显然对于Icon来说是可以的。我希望MSDN能更明确地说明这一点...)


值得指出的是,这里“节省”的字节与写入文件的字节完全相同(因此包括文件头、任何适用的压缩等),而不是图像本身的字节。 - Neil N
是的,如果需要,您可以将其制作成位图并提取像素数组。 - Lasse Espeholt
只是好奇,你在MemoryStream中很好地使用了using-block,为什么在反向的BytesToIcon方法中不同等呢?不再需要处理ms? - Abel
我可以验证Icon在构建时立即读取流。 - BC.
@BC:谢谢 - 现在已经用 using 语句包装好了 :) - Jon Skeet
谢谢!我在位图转换的路上遇到了瓶颈。 - emptyset

2

1
不要调用GetBuffer - 它可能会在末尾有多余的0。使用ToArray是正确的方法。 - Jon Skeet
谢谢,我注意到了。我只是从链接中复制了一些东西。里面有多个解决方案。在谷歌上只用了20秒 :) - Lasse Espeholt

1

...然后再返回

public static Icon IconFromBytes(byte[] bytes) {
     using(var ms = new MemoryStream(bytes)) {
          return new Icon(ms);
     }
}

Icon类在构造时立即从流中读取。关闭MS没有任何问题。


能具体解释一下吗?我同意MemoryStream不需要处理,因为它没有非受控资源……但它强调了当实现IDisposable时调用处理的整个概念。 - BC.
@Hans Passant:不确定您的意思,但也许您是想问Dispose是什么?如果一个类实现了IDisposable,那么将其包装在using块中几乎是强制性的。由于.NET中缺少多重继承,某些类实现了IDisposable,尽管它们在技术上不需要。MemoryStream是一个实现了非托管代码(WaitHandle)的类,需要使用using或try/finally。这里应用得很正确。在不需要的情况下(一些IComponent的实现),为了清晰起见,通常最好仍然使用using - Abel
PS:如果需要示例,请查看Jon Skeet在我的Dispose评论后如何更正自己的代码。 - Abel
嗯,我们必须就这个问题达成不同意的共识。请注意,我实际上并没有投反对票,只是想挑战一下。 - Hans Passant

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