Question

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 BitmapSource 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?

Was it helpful?

Solution

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

OTHER TIPS

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];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top