Having trouble with BitmapSource object in C#
I'm attempting to manipulate an image, I'm fairly new when it comes to Bitmaps and images so bare with my on my question and code. I'm initializing an byte array to hold Bgr24 pixel data so I can pass it into a B开发者_C百科itmapSource object. But my pixel array is not the correct size "I think".
The last line of code is actually where my problem is, the parameter "pixels" is throwing me the following error "System.ArgumentException was unhandled Value does not fall within the expected range."
I initialize these variables
int imageSize = 100;
double dpi = 96;
int width = 128;
int height = 128;
byte[] pixels = new byte[width * height * 3];
//Create my image....
for (int i = 0; i < imageSize; i++)
{
for (int j = 0; j < imageSize; j++)
{
int ct = myImage[i, j];
pixels[i * imageSize * 3 + j + 0] = (byte)((ct % 16) * 14);
pixels[i * imageSize * 3 + j + 1] = (byte)((ct % 32) * 7);
pixels[i * imageSize * 3 + j + 2] = (byte)((ct % 128) * 2);
}
}//end for
//Create the bitmap
BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgr24, null, pixels, width);
I understand that I am not setting up the pixels array correctly. Any thoughts?
"Value does not fall within the expected range" is the message for the ArgumentException that HRESULT.Check
throws when a WIC function (the native API underlying WPF imaging functionality) returns WINCODEC_ERR_INVALIDPARAMETER
.
In this case, the problem is that the final parameter to BitmapSource.Create
should be the "stride" of the bitmap (not the width). A bitmap's "stride" is the (integral) number of bytes required to store each row of the bitmap. As per this MSDN magazine article, the general formula for calculating the stride is stride = (width * bitsPerPixel + 7) / 8;
. For a 24bpp bitmap, this simplifies to width * 3
.
To prevent the exception, pass in the correct stride value:
BitmapSource bmpSource = BitmapSource.Create(width, height, dpi, dpi, PixelFormats.Bgr24, null, pixels, width * 3);
Here is some code I use when working with Bitmaps...
private const int cRedOffset = 0;
private const int cGreenOffset = 1;
private const int cBlueOffset = 2;
private const int cAlphaOffset = 3;
var width = bmp.Width;
var height = bmp.Height;
var data = bmp.LockBits(Rectangle.FromLTRB(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
var stride = data.Stride;
var pixels = new byte[height * stride];
Marshal.Copy(data.Scan0, pixels, 0, height * stride);
for (var row = 0; row < height; row++)
{
for (var col = 0; col < width; col++)
{
var pixel = (row * stride) + (col * 4);
var red = pixels[pixel + cRedOffset];
var green = pixels[pixel + cGreenOffset];
var blue = pixels[pixel + cBlueOffset];
var alpha = pixels[pixel + cAlphaOffset];
}
}
精彩评论