计算用于WriteableBitmap.WritePixels方法所需的缓冲器大小(Calculat

2019-07-05 22:29发布

如何计算的WriteableBitmap.WritePixels方法所需的缓冲区大小?

我使用的过载需要四个参数,第一个是一个Int32Rect,接下来是包含该颜色的RGBA数字的字节数组,第三是步幅(这是我的可写的位图的乘以划分每个像素的比特宽度通过8),最后是缓冲器(称为在智能感知的偏移)。

我得到的缓冲区大小是不是在下面的代码足够的运行时错误:

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);

什么是我需要使用计算在上面的代码所需要的缓冲值的公式?

Answer 1:

步幅值被计算为每在写入矩形“像素行”的字节数:

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

所需的缓冲区大小是每行乘以行数的字节数:

var bufferSize = rect.Height * stride;

只要你有一个2x2的写入矩形和一个32位每像素格式,如PixelFormats.Pbgra32 ,你stride为8和缓冲区大小为16。



Answer 2:

步幅是只需在您输入缓冲区的字节宽度。 这就是所谓的步幅,因为有时有这样的图像的每一行,这使得不可能使用图像的宽度,以读出的图像的每一行后面额外存储器。

因此,在你的榜样,这是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。



Answer 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 }));
        }


Answer 4:

我有这方面的工作。 60Z FS

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


Answer 5:

虽然用户克莱门斯回答关于缓冲区大小的问题,提问者并不知道他计算出的缓冲区大小已经是正确的,问题是其他地方。

虽然给出的意见讨论的细节还有缺乏一个全面的片段(和.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);


Answer 6:

我不知道,但尝试这个工程的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));

   }


文章来源: Calculating the required buffer size for the WriteableBitmap.WritePixels method