I'm trying to display a preview of a 16bit RAW image in my WPF application but it's not working as I was hoping it would. I've had a look at countless of examples, questions/answers here on SA and even on CodeProject but that didn't take me far, either. Well, actually it did since I can completely load an 8bit grayscale RAW image and display it on the application without any weird artifacts whatsoever, but when it comes to 16 bit images it get's all messed up.
Here's an example of how it should look: https://i.stack.imgur.com/kSCX5.jpg
And this is what I get when trying to load a 16bit version of the same raw image (directly exported as 16bit from a third-party program): https://i.stack.imgur.com/Melmk.jpg
Loading the 16bit image as 8bit gives me half of the correct image.
These are my import functions:
BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open));
private void LoadRAWData8bit()
{
int bits = format.BitsPerPixel;
int stride = ((width * bits + (bits - 1)) & ~(bits - 1)) / 8;
byte[] pixels = new byte[stride * height];
for (int i = 0; i < br.BaseStream.Length; ++i)
pixels[i] = br.ReadByte();
br.Close();
BitmapSource bmp = BitmapSource.Create(width, height, 96, 96, format, null, pixels, stride);
RawFile = new CRAW(new Size(width, height), format, stride, bmp);
}
// 16bit load Test
private void LoadRAWData16bit()
{
WriteableBitmap wBmp = new WriteableBitmap(width, height, 96, 96, format, null);
int bpp = format.BitsPerPixel / 8;
byte[] pixels = new byte[wBmp.PixelWidth * wBmp.PixelHeight];
Int32Rect drawRegionRect = new Int32Rect(0, 0, wBmp.PixelWidth, wBmp.PixelHeight);
for (int i = 0; i < br.BaseStream.Length; ++i)
pixels[i] = br.ReadByte();
br.Close();
int stride = wBmp.PixelWidth * bpp;
wBmp.WritePixels(drawRegionRect, pixels, stride, 0);
RawFile = new CRAW(new Size(width, height), format, stride, wBmp);
}
(Please don't mind the parameters passed to the CRAW class, I'm only experimenting for now until I can get this to work correctly.)
Am I missing a step? Does anyone know how to get this to work? I've tried to make the very same 8bit import function with an ushort array instead of a byte array:
private void LoadRAWData16bit()
{
int bits = format.BitsPerPixel;
int stride = ((width * bits + (bits - 1)) & ~(bits - 1)) / 8;
int bpp = format.BitsPerPixel / 8;
ushort[] pixels = new ushort[stride * height * bpp];
for (int i = 0; i < br.BaseStream.Length; i += sizeof(ushort))
pixels[i] = br.ReadUInt16();
br.Close();
BitmapSource bmp = BitmapSource.Create(width, height, 96, 96, format, null, pixels, stride);
RawFile = new CRAW(new Size(width, height), format, stride, bmp);
}
like this, but doing so gives me half the image and it's alot darker than it's supposed to be because there's 1 byte every 2nd byte in the array having a value of 0. Doing pixels[i / 2] gives me again the same image like mentioned before (16bit loading sample).
Loading the 16bit raw image into Photoshop shows the import dialog which suggests a Channel count of 2 as 8bit (setting it to 16 bit with 2 Channels won't let me import it, but 16 bit with 1 Channel works).
This would explain why loading the 16bit image as 8bit into my WPF application only imports half of it.. but that leaves me with a big questionmark as to why it's not loading the 2nd channel too.
This subject is poorly documented and barely discussed anywhere. Can't find anything anywhere on this matter.. Hope to find someone who's able to help me out.
Thanks and happy new year!