3 回答

TA貢獻(xiàn)2021條經(jīng)驗(yàn) 獲得超8個(gè)贊
關(guān)于你的問(wèn)題4:在ImageLockMode.UserInputBuffer能給你可能被引用到的那些記憶大量的分配過(guò)程的控制BitmapData對(duì)象。
如果選擇創(chuàng)建自己的BitmapData對(duì)象,則可以避免使用Marshall.Copy。然后,您將不得不將此標(biāo)志與另一個(gè)標(biāo)志結(jié)合使用ImageLockMode。
注意這是一項(xiàng)復(fù)雜的業(yè)務(wù),特別是與Stride和PixelFormat有關(guān)。
這是一個(gè)示例,將一張照片中的24bbp緩沖區(qū)的內(nèi)容放入一個(gè)BitMap中,然后另一張照片將其讀回到另一個(gè)緩沖區(qū)中,并將其讀入48bbp。
Size size = Image.Size;
Bitmap bitmap = Image;
// myPrewrittenBuff is allocated just like myReadingBuffer below (skipped for space sake)
// But with two differences: the buff would be byte [] (not ushort[]) and the Stride == 3 * size.Width (not 6 * ...) because we build a 24bpp not 48bpp
BitmapData writerBuff= bm.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.UserInputBuffer | ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb, myPrewrittenBuff);
// note here writerBuff and myPrewrittenBuff are the same reference
bitmap.UnlockBits(writerBuff);
// done. bitmap updated , no marshal needed to copy myPrewrittenBuff
// Now lets read back the bitmap into another format...
BitmapData myReadingBuffer = new BitmapData();
ushort[] buff = new ushort[(3 * size.Width) * size.Height]; // ;Marshal.AllocHGlobal() if you want
GCHandle handle= GCHandle.Alloc(buff, GCHandleType.Pinned);
myReadingBuffer.Scan0 = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);
myReadingBuffer.Height = size.Height;
myReadingBuffer.Width = size.Width;
myReadingBuffer.PixelFormat = PixelFormat.Format48bppRgb;
myReadingBuffer.Stride = 6 * size.Width;
// now read into that buff
BitmapData result = bitmap.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.UserInputBuffer | ImageLockMode.ReadOnly, PixelFormat.Format48bppRgb, myReadingBuffer);
if (object.ReferenceEquals(result, myReadingBuffer)) {
// Note: we pass here
// and buff is filled
}
bitmap.UnlockBits(result);
handle.Free();
// use buff at will...
如果您使用ILSpy,則會(huì)看到此方法鏈接到GDI +,這些方法的幫助更加完整。
您可以通過(guò)使用自己的內(nèi)存方案來(lái)提高性能,但是請(qǐng)注意,Stride可能需要進(jìn)行一些調(diào)整才能獲得最佳性能。
然后,您將可以例如分配巨大的虛擬內(nèi)存映射的scan0并非常有效地blit它們。請(qǐng)注意,固定巨大的數(shù)組(尤其是少數(shù)數(shù)組)不會(huì)給GC造成負(fù)擔(dān),并且可以讓您以完全安全的方式(或者如果您追求速度則不安全)來(lái)操縱字節(jié)/短路。

TA貢獻(xiàn)2016條經(jīng)驗(yàn) 獲得超9個(gè)贊
我不確定您是否會(huì)按照自己的方式進(jìn)行操作。也許有。似乎您走得太遠(yuǎn)了,所以您可能要嘗試做一些比問(wèn)題標(biāo)題所暗示的要高級(jí)的事情...
但是,從字節(jié)數(shù)組創(chuàng)建位圖的傳統(tǒng)方法是:
using (MemoryStream stream = new MemoryStream(byteArray))
{
Bitmap bmp = new Bitmap(stream);
// use bmp here....
}
- 3 回答
- 0 關(guān)注
- 599 瀏覽
添加回答
舉報(bào)