2013-06-27 149 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

感謝您的回答。 –

相關問題