簡體   English   中英

Visual Basic-將位圖像素獲取為數組

[英]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數據的實際像素格式。 這對於找到正確的字節很重要

寬度鎖定圖像的寬度

高度鎖定圖像的高度

Scan0Stride與內存中的數組的關系如下所示:

的BitmapData

如圖所示, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM