2013-10-07 171 views
2

我用下面的代碼克隆位圖圖像不鎖定原始文件鎖定。但是我正面臨克隆圖像(.Gif)與原始圖像不一樣的問題。特別是,克隆圖像的顏色不合適。需要克隆位圖圖像,而不對原始圖像

我做錯了什麼?有沒有更好的方法讓內存中的圖像和原始文件從硬盤上刪除?

代碼:

private Bitmap CloneImage(Bitmap src) 
    { 
     if (src == null) 
      return src; 
     Bitmap bitmap = new Bitmap(src.Size.Width, src.Size.Height, src.PixelFormat); 
     System.Drawing.Rectangle bounds = new System.Drawing.Rectangle(0, 0, src.Width, src.Height); 
     System.Drawing.Imaging.BitmapData bmpData = src.LockBits(bounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, src.PixelFormat); 
     System.Drawing.Imaging.BitmapData newBmpData = bitmap.LockBits(bounds, System.Drawing.Imaging.ImageLockMode.ReadWrite, src.PixelFormat); 
     IntPtr bPtr = bmpData.Scan0; 
     IntPtr nbPtr = newBmpData.Scan0; 
     int bytes = Math.Abs(bmpData.Stride) * src.Height; 
     byte[] rgbValues = new byte[bytes]; 

     System.Runtime.InteropServices.Marshal.Copy(bPtr, rgbValues, 0, bytes); 
     System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, nbPtr, bytes); 
     bitmap.UnlockBits(newBmpData); 
     src.UnlockBits(bmpData); 
     return bitmap; 
    } 

原始圖像:

Original Image

克隆的映像:

Cloned Image

+0

有什麼'src.PixelFormat'在運行時?什麼是跨越式的價值?這看起來像一個調色板問題。各個像素位於正確的位置,因此memcpy代碼可能是正確的。 – usr

+2

我猜PixelFormat是Format8bppIndexed,並且生成的圖像具有正確的像素信息,只是錯誤/錯誤的顏色表。 – sisve

+0

你有沒有試過'位圖結果=新的位圖(源);'? – Rotem

回答

3

這看起來像一個調色板問題。各個像素位於正確的位置,因此memcpy代碼可能是正確的。

要麼複製調色板,要麼使用24或32位像素格式,並使用Graphics.FromImage將源圖像移動到目標位圖上。然後你可以保存爲PNG,這可能會成爲一個更小的文件。

+0

感謝您的回答...複製原始文件的調色板就像一個魅力... – Amsath

1

這是比較容易(更少的代碼)通過將其保存到一個MemoryStream克隆圖像。然後你可以從MemoryStream中加載它,並且你將擁有你的克隆位圖,你不必亂用像素格式。

+0

謝謝您的回答。 但使用內存流將導致我的應用程序是一個圖像處理的應用程序也可以用來處理一些大量圖像高品質的問題,這導致增加應用程序的內存。 – Amsath

+0

@learner你可以[壓縮](http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx)流。 – Sam

+1

現有的代碼已經使用額外的內存,Bitmap也不是免費的。該流已被編碼器壓縮。 –

0

根據這一SO answer,你在做什麼,在這裏應該是硬如,

private Bitmap CloneImage(Bitmap src) 
{ 
    return new Bitmap(src); 
}