2010-04-28 66 views
1

我使用.resx文件將圖像嵌入到我的程序集中。運行時,我需要將圖像保存到獨立文件中,恢復原始內容。我如何從System.Drawing.Bitmap實例中提取原始文件流?我知道我可以使用Bitmap.Save()創建一個流,但是即使在將PNG保存爲PNG時,也會對圖像進行轉碼(並且實際上會膨脹)這些圖像。如何從System.Drawing.Bitmap對象中提取原始圖像流?

或者我的錯誤是將它們從Resource作爲Bitmap排在第一位?

回答

2

是的,一旦您將其作爲Bitmap對象讀取,您將無法獲取原始文件流。 Bitmap對象只包含未壓縮的數據,而不包含原始數據。

您應該將資源讀取爲字節數據intead。您可以從資源流讀取和寫入文件:

using (Stream source = this.GetType().Assembly.GetManifestResourceStream("WindowsApplication1.filename.jpg")) { 
    using (FileStream dest = File.Create(fileName)) { 
    byte[] buffer = new byte[4096]; 
    while (true) { 
     int len = source.Read(buffer, 0, buffer.Length); 
     if (len == 0) break; 
     dest.Write(buffer, 0, len); 
    } 
    } 
} 

注:這需要添加的圖像作爲嵌入式資源,而不是一個管理資源。您可以使用Image.FromStream()從中創建一個Image

1

如果你沒有實際使用Bitmap在你機應用顯示的目的(即您剛剛提取的資源爲位圖,以便您可以將其保存爲一個文件),那麼最簡單的方法只是將資源作爲Stream並將其保存到文件中。

本教程介紹瞭如何獲得資源流:

http://devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=75

在樣本中,筆者得到一個流,並將其傳遞給Bitmap.FromStream方法。你會做的只是將該流直接保存到文件中(完全繞過Bitmap)。

2

我不明白這個問題。 PNG是一種無損格式,你會得到完全相同的圖像。是的,當您保存()時,您不一定會得到完全相同的字節。這是一種壓縮格式,壓縮器在壓縮和速度之間達到最佳平衡的時間可能不盡相同。但是,那又如何?

如果這是一個真正的問題,那麼你不應該添加圖像作爲託管資源。您可以將其作爲嵌入式資源添加到項目中,並使用Assembly.GetManifestResourceStream()從元數據中讀取它。你會得到原始圖像文件字節。使用Image.FromStream()可轉換爲圖像。

+0

我還保存jpg和.gif和圖像文件由圖形設計師相當嚴重優化。但是我現在使用的解決方案(以及其中的工作方式)是基於嵌入式資源而不是託管的,正如您所寫的 - 這是有效的。 – skolima 2010-04-29 06:49:43

0

原來的問題是在使用管理的資源 - RESX建設者創造從位圖圖像文件對象和序列化這些對象,它不存儲原始文件流。但是,嵌入式資源可以存儲平面二進制文件。

我現在從嵌入我的圖片中的所有文件使用以下.csproj項文件夾:

<EmbeddedResource Include="Images\*.jpg" /> 
<EmbeddedResource Include="Images\*.png" /> 
<EmbeddedResource Include="Images\*.gif" /> 

的Visual Studio顯示他們作爲正常項目文件與Build Action設置爲Embedded Resource

然後,從我的代碼,我加載與原來的文件流:

var assembly = GetType().Assembly; 
var regex = new Regex("\\.(png|jpg|gif))$"); 
foreach (var bitmap in assembly.GetManifestResourceNames()) 
{ 
    if(!regex.IsMatch(bitmap) 
    continue; 

    var stream = assembly.GetManifestResourceStream(bitmap); 
    //handle the stream here 
}