1

I know this is mostly an image question not code, but I'll give it a shot here.

So first I have a 8bits/pixel grayscale image(bitmap). Which means that each pixel is represented into 1 byte. This means that the the pixel value is the byte value. Clear enough.

But then...

I have a 16bits/pixel grayscale image (bitmap). Which means that each pixel is represented into 2 bytes. This is clear for me. Now I create a byte[] array that will hold each byte value.

For an 1024x1024 image I will have 2097152 bytes. It's 1024*1024*2.

My question is now, how do I get the pixel value for a specific pixel.

Let's say for pixel at position(X|Y) the bytes are 84 and 77. How do I transform these 2 values into the pixel value.

Firstly I need this for some calculation where I need the pixel value, then I want to change the color palette of the bitmap and it works fine with 8 bitsperpixel images, but doesn't for 16bitsperpixel images.

Any help would be nice.

 var width = bitmap.PixelWidth;
            var height = bitmap.PixelHeight;
            var dpiX = bitmap.DpiX;
            var dpiY = bitmap.DpiY;

            byte[] pixels = new byte[
                     bitmap.PixelHeight * bitmap.PixelWidth *
                         bitmap.Format.BitsPerPixel / 8];

            bitmap.CopyPixels(pixels, bitmap.PixelWidth * bitmap.Format.BitsPerPixel / 8, 0);

This is how I create the array of pixels.

CiucaS
  • 2,010
  • 5
  • 36
  • 63
  • @Clemens public virtual void CopyPixels(Array pixels, int stride, int offset); The third argument is the offset. The second argument is the stride. – CiucaS Jan 29 '20 at 13:59
  • Oh, sorry for the confusion. If you "*want to change the color palette of the bitmap*" you should use an indexed format anyway, perhaps Indexed8. – Clemens Jan 29 '20 at 13:59
  • Sorry I don't follow. I guess the pixel value for 2 byte would be the multiplying of the 2 bytes ( 84*77 = 6468). But this value is way out of range of my 0..255 interval ( 8 bits) – CiucaS Jan 29 '20 at 14:03
  • 1
    A 16-bit pixel value has a range of 0..65535. The value would be calculated as (256 * 84) + 77. – Clemens Jan 29 '20 at 14:27
  • So that means if I want to transform the 16bit to 8bit would be 84/256 + 77? – CiucaS Jan 29 '20 at 14:33
  • No, you would just divide the 16-bit value by 256. Maybe let WPF do it for you by means of a FormatConvertedBitmap. – Clemens Jan 29 '20 at 14:36

1 Answers1

1

It may be easier to use a 2-byte type for the pixel array:

var width = bitmap.PixelWidth;
var height = bitmap.PixelHeight;
var pixels = new ushort[width * height];

bitmap.CopyPixels(pixels, 2 * width, 0);

Access an individual pixel value directly from that array:

var x = 100;
var y = 200;
var pixel = (int)pixels[width * y + x];

In order to convert the 16bpp pixel array into a 8bpp array, just divide each pixel value by 256

var pixels8bpp = pixels.Select(p => (byte)(p / 256)).ToArray();

and create a 8bpp BitmapSource by

var bitmap8bpp = BitmapSource.Create(
    width, height, 96, 96, PixelFormats.Gray8, null, pixels8bpp, width);
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Thanks, I will try this tomorrow, but looks like something I need. – CiucaS Jan 29 '20 at 18:23
  • Thank you, I managed to adept my code using information from your response and I think I got where I wanted to be. Much thanks! – CiucaS Jan 30 '20 at 13:42