2011-07-27 94 views
3

在操縱Bitmap對象的基礎字節以消除圖像的透明度方面苦苦掙扎。 我有一個靜態移除透明​​度的方法,採用一個位圖對象,培訓相關代碼:http://pastebin.com/ZjjPSdx8C#中的位圖字節操作

現在,當我把這種基於文件的位圖對象,該位不被突變。如果我理解正確的話,這是因爲它是基於一個文件按http://support.microsoft.com/kb/814675

所以創建了一個方法來複制位圖: http://pastebin.com/9rXRJ6cx

private Bitmap LoadBmp(string name) 
    { 
     Assembly asm = Assembly.GetExecutingAssembly(); 
     string loc = Path.GetDirectoryName(asm.Location); 
     string path = Path.Combine(loc, "Images\\" + name); 
     Bitmap notsafe = (Bitmap)Bitmap.FromFile(path); 
     return ImageProcessor.SafeBitmap(notsafe); 
... 

所有罰款和花花公子。適用於PNG,但不適用於GIF。他們出來了可怕的 扭曲。

嘗試的另一種方法的文件寫入到一個字節數組,然後基礎上,該位圖:

 byte[] b = new byte[2048]; 
     int c; 
     byte[] imgArr; 
     using (FileStream fs = new FileStream(path, FileMode.Open)) 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       while ((c = fs.Read(b, 0, b.Length)) > 0) 
        ms.Write(b, 0, c); 
       imgArr = ms.ToArray(); 
      } 
     } 

     return (Bitmap)Bitmap.FromStream(new MemoryStream(imgArr)); 

這不會扭曲GIF的。但是我的刪除透明度方法不再適用於PNG! 顯然我做錯了什麼,希望有人可以幫忙!

+1

與你的問題沒有直接關係,但是如果'File'對象有一個美妙的'ReadAllBytes()'方法''System.IO.File.ReadAllBytes()' –

回答

4

編輯:

從文件加載這樣時,你可以解決你的不變位的問題:

var bmp = new Bitmap(Image.FromFile("C:\bmp.bmp"))

阻止你做任何Marshal.Copy(這是慢) ,它也解決了您的GIF變得殘缺和扭曲的問題。如果你有興趣,其這樣做,內部.NET代碼如下:

g = Graphics.FromImage(this); 
g.Clear(Color.Transparent); 
g.DrawImage(original, 0, 0, width, height); 

所以它實際上是我給你以下,解決您的透明度問題,這不符合您的需求速度的代碼。的(5.6 seconds g.FromImage vs 6.4 seconds yours with 1000 gifs @ 543x341)

理論上

但是,如果你能做到的負荷,並在通過g.FromImage同時複製,我有速度,你可以讓你更快,當你將複製和刪除透明度相同的功能。如果您在不改寫圖像的情況下加載GIF,它將採用不同的像素格式,實際上,8bppindexed,這意味着您的功能將無法正常工作。無論哪種方式,上面的解決方案將解決使用CheckIfTransparent函數時的問題,下面的解決方案(我不得不編輯它)會更快。如果我願意的話,我可能會花一些時間來看。我覺得這個問題很有趣。

我注意到你的算法去除了alpha並不完全準確。我不確定究竟在哪裏,但是在使用透明漸變時,你的算法看起來不正確。使用直接GDI的那個看起來和預期的一樣。我會確保你正確地轉換顏色。


如果你只是想刪除一個PNG或GIF的透明度,做這一切Marshal.Copy和不安全的代碼,爲什麼不創建一個新的位圖,畫白色的背景,然後覆蓋在退出PNG/gif嗎?似乎不那麼複雜的代碼。

編輯:事情是這樣的:

public static Bitmap ManagedSafeBitmap(string file) 
    { 
     using (var img = Image.FromFile(file)) 
     { 
      var bmp = new Bitmap(img.Width, img.Height); 
      bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution); 
      using (Graphics g = Graphics.FromImage(bmp)) 
      { 
       g.Clear(Color.White); 
       g.DrawImage(img, 0, 0); 
      } 

      return bmp; 
     } 
    } 

這會給你一個新的形象有一個白色背景,並把源圖像最重要的是,有效地改變全透明像素Color.White或什麼顏色你想要通過g.Clear()

+0

想想更大的圖片! –

+0

是的,原來是這樣做的,但是想擠出更多的速度。託管方法比MakeSafe和CleanTransparent的組合速度慢大約50%。如果沒有安全措施(儘管承認它沒有這個功能就行不通了),它的速度慢了300%。 我會處理很多圖像,以便速度差異很重要...(百萬)。 – user865864

+0

請參閱我上面的編輯。 –

0

我想嘗試WriteableBitmap類。我聽說只是爲了使用託管代碼進行像素操作而創建的。