[英]Visual Basic - Get Bitmap pixels as array
我正在使用.NET Framework 4在Visual Basic中制作游戲。是否有與此類似的內容(來自Java):
private int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
對於位圖? 謝謝。
您正在尋找LockBits
方法。
Bitmap
類提供LockBits
和相應的UnlockBits
方法,使您可以修復內存中位圖像素數據數組的一部分,直接訪問它,最后用修改后的數據替換位圖中的位。 LockBits
返回一個BitmapData
類,該類描述了鎖定數組中數據的布局和位置。
BitmapData
類包含以下重要屬性;
Scan0固定數據陣列內存中的地址
跨度單行像素數據的寬度(以字節為單位)。 該寬度是圖像像素尺寸的倍數,或者可能是數倍,並且可以填充以包括更多字節。
PixelFormat數據的實際像素格式。 這對於找到正確的字節很重要
寬度鎖定圖像的寬度
高度鎖定圖像的高度
Scan0和Stride與內存中的數組的關系如下所示:
如圖所示, Stride屬性保留一行的寬度(以字節為單位)。 但是,行的大小可能不是像素大小的精確倍數,因為為了提高效率,系統確保將數據打包到以四個字節為邊界的行中,並填充為四個字節的倍數。 例如,這意味着一個17位寬的每像素24位圖像的步幅為52。每行中使用的數據將占用3 * 17 = 51字節,而1字節的填充將每行擴展為52字節或13 * 4字節 一個17像素寬的4BppIndexed圖像的步幅為12。其中9個字節(或更合適的是8個半字節)將包含數據,並且該行將被另外3個字節填充到4字節邊界。
如上所述,該行的數據承載部分根據像素格式進行布局。 包含RGB數據的每像素24位圖像將每3個字節有一個新像素,每像素RGBA每4個字節有32位。 每字節包含一個以上像素的像素格式(例如,每個像素索引4位和每個像素索引1位)必須謹慎處理,以使所需像素不會與同一字節中的近鄰像素混淆。
找到正確的字節。
因為跨步是行的寬度,所以要索引任何給定的行或Y坐標,可以將跨步乘以Y坐標以獲得特定行的開始。 在行中查找正確的像素可能會更加困難,並且取決於了解像素格式的布局。 以下示例說明如何訪問給定像素格式的特定像素。
Format32BppArgb給定X和Y坐標,像素中第一個元素的地址為Scan0 +(y * stride)+(x * 4)。 這指向藍色字節。 接下來的三個字節包含綠色,紅色和Alpha字節。
Format24BppRgb給定X和Y坐標,像素中第一個元素的地址為Scan0 +(y * Stride)+(x * 3)。 這指向藍色字節,然后是綠色和紅色。
Format8BppIndexed給定X和Y坐標,字節的地址為Scan0 +(y * Stride)+ x。 該字節是圖像調色板的索引。
Format4BppIndexed給定X和Y坐標,將包含像素數據的字節計算為Scan0 +(y * Stride)+(x / 2)。 相應的字節包含兩個像素,兩個像素中最上面的半字節為最左邊,最下面的半字節為最右邊。 上下半字節的四位用於從16個調色板中選擇顏色。
Format1BppIndexed給定X和Y坐標,包含像素的字節由Scan0 +(y * Stride)+(x / 8)計算。 該字節包含8位,每個位是一個像素,第8位為最左邊的像素,第0位為最右邊的像素。這些位從兩個輸入調色板中選擇。
對於每個像素一個或多個字節的像素格式,公式很簡單,可以通過按順序遍歷所有Y和X值來實現。 下面的代碼將每像素32位圖像的藍色分量設置為255。在兩種情況下,bm都是先前創建的位圖。 在c#中,將使用unsafe
塊中的指針:
BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);
int PixelSize=4;
for(int y=0; y<bmd.Height; y++)
{
byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
for(int x=0; x<bmd.Width; x++)
{
row[x*PixelSize]=255;
}
}
在VB中,此操作將有所不同,因為VB不了解指針,並且需要使用marshal類來訪問非托管數據。
Dim x As Integer
Dim y As Integer
Dim PixelSize As Integer = 4
Dim bmd As BitmapData = bm.LockBits(new Rectangle(0, 0, 10, 10), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat)
For y = 0 To bmd.Height - 1
For x = 0 To bmd.Width - 1
Marshal.WriteByte(bmd.Scan0, (bmd.Stride * y) + (4 * x) , 255)
Next
Next
* Bob Powell的代碼和文章,摘自Internet存檔
不知道為什么您可能需要這樣做,但是GetPixel和SetPixel可以正常工作以編輯或檢索像素的顏色。
Bitmap.GetPixel(X, Y) ' Returns a color.
Bitmap.SetPixel(X, Y, Color)
希望這對您有所幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.