2012-12-19 52 views
14

如何計算WriteableBitmap.WritePixels方法所需的緩衝區大小?計算WriteableBitmap.WritePixels方法所需的緩衝區大小

我使用重載取四個參數,第一個是Int32Rect,下一個是包含顏色的RGBA數字的字節數組,第三個是stride(這是我寫的位圖的寬度乘以每像素位數除以8),最後一個是緩衝區(在Intellisense中稱爲偏移量)。

我收到緩衝區大小不足以運行時錯誤在下面的代碼:

byte[] colourData = { 0, 0, 0, 0 }; 

var xCoordinate = 1; 
var yCoordinate = 1; 

var width = 2; 
var height = 2; 

var rect = new Int32Rect(xCoordinate, yCoordinate, width, height); 

var writeableBitmap = new WriteableBitmap(MyImage.Source as BitmapSource); 

var stride = width*writeableBitmap.Format.BitsPerPixel/8; 

writeableBitmap.WritePixels(rect, colourData, stride,0); 

什麼公式我需要使用計算在上面的代碼所需要的緩衝值?

+0

當你說RGBA,就肯定有每像素32位。這使得每個像素4個字節。在2x2矩形中,總數爲16字節(4像素×4字節/每像素)。你的'coulorData'顯然太小了。 – Clemens

+0

@Clemens你是說我的步幅太小?如果不能解釋色彩數據太小,我不明白。 Thankyou – JMK

+0

步幅只是緩衝區中每行的字節數。每行2像素(即寫矩形的寬度)每個像素4個字節,導致步幅爲8. – Clemens

回答

11

跨距值被計算爲在寫入矩形每「像素行」的字節數:

var stride = (rect.Width * bitmap.Format.BitsPerPixel + 7)/8; 

所需的緩衝區大小是乘以行數,每行的字節數:

var bufferSize = rect.Height * stride; 

假設您有一個2x2寫矩形和每像素32位的格式,例如PixelFormats.Pbgra32,你stride爲8和緩衝區大小爲16

+0

hmm,現在我得到一個Index Array of Array錯誤,您是否有任何洞察力? – JMK

+0

「Now」表示您的緩衝區實際上是16個字節長? – Clemens

+0

這是正確的是 – JMK

0

我不知道,但嘗試這個工程的24位RGB

{ 
    //your code 
     var stride = width * 3; 
     WriteableBitmap bmp = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr24, null); 
     bmp.WritePixels(new System.Windows.Int32Rect(0, 0, width , height),byte[],stride,0)); 

    } 
+1

問題是關於如何計算緩衝區大小。 – Clemens

+0

而且,由於您爲像素參數寫入了byte [],因此該代碼無法編譯。 – Clemens

3

的步幅是隻需在您輸入緩衝區的字節寬度。它被稱爲步幅,因爲有時在圖像的每一行後面會有額外的內存,這使得不可能使用圖像的寬度來讀取圖像的每一行。

因此,在你的榜樣,這是2,不需要每個位圖的像素位來計算的話,就是WritePixels方法知道所有這些信息。您需要提供有關輸入數據結構的信息。

但是,正如在其他答案中所述,如果位圖也是2x2,則您的示例將不起作用。那麼起始座標將是0,0。

編輯:

當我看着你的榜樣近,我看到的錯誤。你說colourData是輸入顏色。但是這是每個像素的輸入。所以,如果你想改變的2x2的矩形,你需要以下inputdata:

byte[] colourData = { 0, 0, 0, 0, 0, 0, 0, 0, 
         0, 0, 0, 0, 0, 0, 0, 0 }; 

然後每個像素的字節等於位圖的,所以這是4倍每條線的寬度( 2),總計爲8.

+0

「所以在你的例子中,這是2」是錯誤的。步幅是2(像素)* 4(每像素字節)== 8(字節)。 「 – Clemens

+0

」您不需要計算任何位圖每個像素的位數「也是錯誤的。要從寫入矩形的寬度計算跨度,需要每個像素的字節數。 – Clemens

+0

在他的例子中,我清楚地看到他的輸入數據中有4個字節,所以每個像素1個字節。它不是關於位圖的每個像素的字節數,而是關於輸入數據的每個像素的字節數。 – Geerten

1

我正在與此工作。 60Z FS

this.playerOpacityMaskImage.WritePixels(
       new Int32Rect(0, 0, this.depthWidth, this.depthHeight), 
       this.greenScreenPixelData, 
       this.depthWidth * ((this.playerOpacityMaskImage.Format.BitsPerPixel + 7)/8), 
       0); 
3

下面是微軟的反映執行中CopyPixels

 int num = ((sourceRect.Width * this.Format.BitsPerPixel) + 7)/8; 
     if (stride < num) 
     { 
      throw new ArgumentOutOfRangeException("stride", MS.Internal.PresentationCore.SR.Get("ParameterCannotBeLessThan", new object[] { num })); 
     } 
     int num2 = (stride * (sourceRect.Height - 1)) + num; 
     if (bufferSize < num2) 
     { 
      throw new ArgumentOutOfRangeException("buffer", MS.Internal.PresentationCore.SR.Get("ParameterCannotBeLessThan", new object[] { num2 })); 
     } 
1

雖然用戶克萊門斯回答有關緩衝區的大小問題的校驗碼,提問者並不知道他計算已經緩衝區大小正確和問題是在別的地方。

儘管在註釋中給出和討論了細節,但缺少一個全面的片段(以及完整的.WritePixels使用示例(不包括.CopyPixels))。 這是(我掃描類似的問題,但是這一直是最好的地方):

var dpiX = 96; 

var writeableBitmap = new WriteableBitmap(width, height, dpiX, dpiX, PixelFormats.Bgra32, null); // Pixelformat of Bgra32 results always in 4 bytes per pixel 
int bytesPerPixel = (writeableBitmap.Format.BitsPerPixel + 7)/8; // general formula 
int stride = bytesPerPixel * width; // general formula valid for all PixelFormats 

byte[] pixelByteArrayOfColors = new byte[stride * height]; // General calculation of buffer size 

// The numbers in the array are indices to the used BitmapPalette, 
//  since we initialized it with null in the writeableBitmap init, they refer directly to RGBA, but only in this case. 
// Choose a light green color for whole bitmap (for not easy to find commented MSDN example with random colors, see https://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap(VS.85).aspx 
for (int pixel = 0; pixel < pixelByteArrayOfColors.Length; pixel += bytesPerPixel) 
{ 
    pixelByteArrayOfColors[pixel] = 0;  // blue (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 1] = 255; // green (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 2] = 0; // red (depends normally on BitmapPalette) 
    pixelByteArrayOfColors[pixel + 3] = 50; // alpha (depends normally on BitmapPalette) 
} 

writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelByteArrayOfColors, stride, 0);