2010-10-13 28 views
2

我想對WPF應用程序中的圖像進行一些處理。但是,我想在運行時修改內存中的BitmapSource的像素。是否有可能從另一個線程不安全地修改內存中的WPF BitmapSource

我目前正在設法使用'不安全'的代碼來對付老式的System.Drawing.Bitmap,它可以處理(鎖定工作區域,擺弄像素)作業。該方法在這篇文章中描述:http://blogs.msdn.com/b/ericgu/archive/2007/06/20/lost-column-2-unsafe-image-processing.aspx

要獲得在WPF這個工作我那麼使用這種方法創建一個WPF的BitmapSource:

BitmapSource destination; 
    IntPtr hBitmap = bitmap.GetHbitmap(); 
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions(); 
    destination = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, sizeOptions); 
    destination.Freeze(); 
    return destination; 

然而,這在內存中創建和我有很多副本真的很想進入那裏,像BitGu例子中EricGu所示的那樣擺弄BitmapSource中的底層位。這可能嗎?

我意識到PixelShaders可以做到這一點,但這是一個涉及多個線程(當在不安全模式下編輯位圖時支持)的學術練習。

在此先感謝

+0

我在另一臺機器上有一些很好的代碼。如果你幾個小時內沒有得到答覆,我會抓住它。我相信我使用了BitmapImage。它來自BitmapSource。我不確定,但我有一種感覺,你將永遠不得不將它轉換爲位圖。雖然有更多優雅的轉換方式。 – Harry 2010-10-13 12:51:46

回答

3

我會告訴你就像我知道的。

首先,您似乎已經知道凍結位圖,然後再將它們返回給主線程。這是一個好的開始。

我曾嘗試通過從BitmapSource派生新的實現來減少複製,並覆蓋將數據從位圖複製出來的虛擬函數。它工作但產生了大量的內存泄漏。從來沒有想過它。

你當然也可以直接從一個字節數組中創建一個BitmapSource(並且失去GDI位圖的開銷)。 msdn docs

你考慮過WriteableBitmap嗎?這是WPF團隊對所有複製的常見抱怨的迴應。

編輯:MSDN明確地說,它可以從後臺線程中使用(WritableBitmap.BackBuffer文檔中):

您可以將後備緩衝指針傳遞給 外部組件和處理其他線程 ,但如果你這樣做,你必須爲你提供 協調。特別是,您必須通過調用 AddDirtyRect方法確保UI線程指定 更改區域,並且UI 線程通過調用 Unlock方法來解鎖緩衝區。

所以,如果你讓UI線程獲得鎖和指針,你可以讓工作線程寫像素。

+0

謝謝,我確實知道WriteableBitmap,但這隻能由單線程IIRC更新。我真的很想在後臺線程中播放圖片,我不認爲這是可能的,對吧? – ConfusedNoob 2010-10-13 13:49:46

+0

是的,這是可能的(見編輯)。 – 2010-10-13 14:15:06

相關問題