2013-06-27 73 views
86

我在制作远程桌面共享应用程序,在该应用程序中捕获桌面图像并压缩它并将其发送到接收器。为了压缩图像,我需要将它转换为byte []。将图像转换为字节数组的最快方法

目前我使用此:

public byte[] imageToByteArray(System.Drawing.Image imageIn) 
{ 
    MemoryStream ms = new MemoryStream(); 
    imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif); 
    return ms.ToArray(); 
} 

public Image byteArrayToImage(byte[] byteArrayIn) 
{ 
    MemoryStream ms = new MemoryStream(byteArrayIn); 
    Image returnImage = Image.FromStream(ms); 
    return returnImage; 
} 

但我不喜欢它,因为我必须将它保存在一个的imageformat并且还可以使用最多资源(慢下来),以及产生不同的压缩结果。我已阅读使用Marshal.Copy和memcpy,但我无法理解他们。

那么有没有其他方法可以达到这个目标?

+0

两者的MemoryStream和图像具有Dispose方法是有用的,确保你正在处理它们,因为这会导致MemoryLeaks。 – abc123

+3

@ abc123:你不需要处理一个'MemoryStream';它是一个完全托管的资源,除非您在远程处理中使用它。在这两种情况下,处置资源都是不恰当的。 –

+1

@JonSkeet有趣,你有没有做过一个基准?查看.net释放对象的速度?我知道DataTable有类似的参数,但GarbageCollector收集使用dispose时分配的内存的速度有明显的差异。 – abc123

回答

33

那么还有其他方法可以实现这个目标吗?

号为了将图像转换为字节数组,你指定图像格式 - 就像你当你将文本转换为字节数组指定的编码。

如果您担心压缩文物,请选择无损格式。如果您担心CPU资源,请选择一种不会打扰压缩的格式 - 例如,只是原始的ARGB像素。但是,这当然会导致更大的字节数组。

请注意,如果你选择一个格式确实包括压缩,有一个在事后再压缩字节数组是没有意义的 - 这是几乎可以肯定有没有益处。

+11

而不是'选择一种无损格式',你可以选择'imageIn.RawFormat',它试图保存原始图像字节而不用进一步重新编码。 –

11

Jon Skeet指出,我不确定你是否会得到任何巨大收益。但是,您可以尝试对TypeConvert.ConvertTo方法进行基准测试,并查看它与使用当前方法的比较。

ImageConverter converter = new ImageConverter(); 
byte[] imgArray = (byte[])converter.ConvertTo(imageIn, typeof(byte[])); 
+0

无法投射'System.Byte []'类型的对象来键入'System.Drawing.Image'。 – user123

9
public static byte[] ReadImageFile(string imageLocation) 
    { 
     byte[] imageData = null; 
     FileInfo fileInfo = new FileInfo(imageLocation); 
     long imageFileLength = fileInfo.Length; 
     FileStream fs = new FileStream(imageLocation, FileMode.Open, FileAccess.Read); 
     BinaryReader br = new BinaryReader(fs); 
     imageData = br.ReadBytes((int)imageFileLength); 
     return imageData; 
    } 
+5

欢迎来到stackoverflow.com,你可以添加一个小细节,解释为什么上面的代码示例有帮助。这是为其他SO用户谁可能不完全了解它... http://stackoverflow.com/help/how-to-answer – Mack

+0

这是文件到字节,但OP希望一个绘图对象转换为字节。绘图对象可以作为字节数组存储在数据库中,不一定是文件系统,因此必须来回转换......但不能将FileStream中的文件转换为字节 - 除非在初始上传。 – vapcguy

+0

这帮助我,因为我正在寻找这样做的文件。好与它有关。 – CPlayer

33

有返回的图像的文件格式的图像参数的RawFormat属性。 你可以尝试以下操作:

// extension method 
public static byte[] imageToByteArray(this System.Drawing.Image image) 
{ 
    using(var ms = new MemoryStream()) 
    { 
     image.Save(ms, image.RawFormat); 
     return ms.ToArray(); 
    } 
} 
+6

我建议要么处置MemoryStream或包装在使用(){}语句 –

+0

@ Neil.Allen这种方法的主体我是新来的请问为什么? –

+2

@FirstStep因为自己清理:) – Sinaesthetic

2

我能找到的最快方法是这样的:

var myArray = (byte[]) new ImageConverter().ConvertTo(InputImg, typeof(byte[])); 

希望能

+0

要小心这一点,特别是如果使用WPF你会有'System.Windows.Controls.Image'对象。如果您想将其中的一个转换为字节,并将其作为“InputImg”传递给此行,则这不起作用。它期望一个'System.Drawing.Image'对象。 – vapcguy

3
public static class HelperExtensions 
{ 
    //Convert Image to byte[] array: 
    public static byte[] ToByteArray(this Image imageIn) 
    { 
     var ms = new MemoryStream(); 
     imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
     return ms.ToArray(); 
    } 

    //Convert byte[] array to Image: 
    public static Image ToImage(this byte[] byteArrayIn) 
    { 
     var ms = new MemoryStream(byteArrayIn); 
     var returnImage = Image.FromStream(ms); 
     return returnImage; 
    } 
} 
+0

感谢您的回答。 –

相关问题