2014-12-04 70 views
2

我通過從另一箇中提取200x200平方來創建一個新的位圖。我認爲源代碼(位圖像素)由這兩者共享。現在,當我在原始圖像上畫一個圓圈時,副本上也有一個圓圈。但是當我這樣做時 - 在新創建的一個上繪製一個圓 - 原始圖上沒有圓圈。爲什麼會發生?我認爲源像素是共享的。在共享源位圖上繪圖

private Bitmap testa(Bitmap bmp) 
    { 
     System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); 

     //Create a new bitmap. 
     Bitmap newBitmap = new Bitmap(200, 200, bmpData.Stride, bmp.PixelFormat, bmpData.Scan0); 

     bmp.UnlockBits(bmpData); 

     // Draw the new bitmap. 
     using (Graphics g = Graphics.FromImage(bmp)) // or: newBitmap 
     { 
      g.DrawEllipse(new Pen(Brushes.Red), 1, 1, 100, 100); 
     } 
     return newBitmap; 
    } 
+0

我不認爲你實際上'分享'像素。你只能複製他們有或沒有圈子。另外:爲什麼不復制DrawImage?它具有這樣的格式! – TaW 2014-12-04 17:22:06

+0

@TaW那麼爲什麼當我先複製圖像並在稍後繪製圖像時,圓形會在兩幅圖像上顯示?對於DrawImage:這只是一個例子,我只有IntPtr才能從不完整的位圖複製。 – user0101 2014-12-04 17:27:30

+0

我們看到了代碼嗎? – TaW 2014-12-04 18:11:02

回答

1

基本上,你已經使用LockBits()Bitmap()構造函數不正確,所以不管你的行爲看,這是純粹的學術的和不確定的。

您傳遞給Bitmap(int, int, int, PixelFormat, IntPtr)構造函數的IntPtr必須是您爲該特定位圖分配的構造函數。您需要確保it remains valid for the lifetime of the Bitmap object

另一方面,BitmapData.Scan0指針保證僅在您致電UnlockBits()之前保持有效。那時,它可能會也可能不會。

如果您好奇,嘗試其他實驗可能會很有趣,例如在原始位圖上繪圖,查看新位圖,然後繪製新位圖,查看原始圖像,然後再次繪製原始圖像,然後查看新的。

但是無論你在這樣一個實驗中發現的行爲如何,你都不能依賴它,因爲行爲沒有記錄和不被支持。據我所知,沒有支持的機制允許兩個不同的Bitmap對象共享相同的緩衝區。它似乎在一些孤立的情況下工作是純粹的運氣。

+0

我沒有閱讀鏈接頁面的評論部分,但我的例子也是從那裏看的。這很好解釋。謝謝 – user0101 2014-12-04 18:22:12

+0

你推薦複製來自IntPtr的位圖是什麼?我應該像這樣創建tmp位圖,然後創建Clone()嗎? – user0101 2014-12-04 18:40:17

+0

親自?我不會嘲笑'LockBits()',除非你的速度比方便性更高。要使位圖完全重複,只需使用「位圖(圖像)」構造函數。如果你想裁剪位圖,創建一個你想要的大小的新的「Bitmap」對象,調用Graphics.FromImage(Image)傳遞新的位圖,然後將你想要的原始位圖的一部分繪製到新的位圖中,使用'Graphics.DrawImage()'方法。 – 2014-12-04 18:46:33