第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

從像素?cái)?shù)據(jù)的字節(jié)數(shù)組創(chuàng)建位圖

從像素?cái)?shù)據(jù)的字節(jié)數(shù)組創(chuàng)建位圖

C#
繁星點(diǎn)點(diǎn)滴滴 2019-12-27 15:30:46
這個(gè)問(wèn)題是關(guān)于如何讀取/寫入,分配和管理位圖的像素?cái)?shù)據(jù)。這是一個(gè)如何為像素?cái)?shù)據(jù)分配字節(jié)數(shù)組(托管內(nèi)存)并使用它創(chuàng)建位圖的示例:Size size = new Size(800, 600);PixelFormat pxFormat = PixelFormat.Format8bppIndexed;//Get the stride, in this case it will have the same length of the width.//Because the image Pixel format is 1 Byte/pixel.//Usually stride = "ByterPerPixel"*Width//但這并不總是正確的。在bobpowell的更多信息。int stride = GetStride(size.Width, pxFormat);byte[] data = new byte[stride * size.Height];GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);Bitmap bmp = new Bitmap(size.Width, size.Height, stride,             pxFormat, handle.AddrOfPinnedObject());//After doing your stuff, free the Bitmap and unpin the array.bmp.Dispose();handle.Free();public static int GetStride(int width, PixelFormat pxFormat){    //float bitsPerPixel = System.Drawing.Image.GetPixelFormatSize(format);    int bitsPerPixel = ((int)pxFormat >> 8) & 0xFF;    //Number of bits used to store the image data per line (only the valid data)    int validBitsPerLine = width * bitsPerPixel;    //4 bytes for every int32 (32 bits)    int stride = ((validBitsPerLine + 31) / 32) * 4;    return stride;}我以為該位圖可以復(fù)制數(shù)組數(shù)據(jù),但實(shí)際上它指向相同的數(shù)據(jù)。您可以看到:Color c;c = bmp.GetPixel(0, 0);Console.WriteLine("Color before: " + c.ToString());//Prints: Color before: Color [A=255, R=0, G=0, B=0]data[0] = 255;c = bmp.GetPixel(0, 0);Console.WriteLine("Color after: " + c.ToString());//Prints: Color after: Color [A=255, R=255, G=255, B=255]問(wèn)題:從byte []數(shù)組(托管內(nèi)存)和free()GCHandle創(chuàng)建位圖是否安全?如果不安全,則需要保留固定的陣列,這對(duì)GC / Performance有多嚴(yán)重?更改數(shù)據(jù)是否安全(例如:data [0] = 255;)?GC可以更改Scan0的地址嗎?我的意思是,我從鎖定的位圖獲取Scan0,然后將其解鎖,再過(guò)一段時(shí)間鎖定后,Scan0會(huì)有所不同嗎?LockBits方法中ImageLockMode.UserInputBuffer的用途是什么?很難找到有關(guān)該信息!MSDN沒有清楚地解釋它!
查看完整描述

3 回答

?
寶慕林4294392

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é)/短路。


查看完整回答
反對(duì) 回復(fù) 2019-12-27
?
慕沐林林

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....

}


查看完整回答
反對(duì) 回復(fù) 2019-12-27
  • 3 回答
  • 0 關(guān)注
  • 599 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)