We have some bitmap images which actually in RAW
format but it uses a windows bitmap format, however if not using the camera provided lib to decode it you cannot have a good result.
The following is the code that works fine:
public static Bitmap DecodeImage(Bitmap raw_image)
{
if (raw_image == null || raw_image.PixelFormat != PixelFormat.Format8bppIndexed)
return null;
BitmapData data_in, data_out;
Bitmap rgb_image = new Bitmap(raw_image.Width, raw_image.Height, PixelFormat.Format24bppRgb);
data_in = raw_image.LockBits(new Rectangle(0, 0, raw_image.Width, raw_image.Height), ImageLockMode.ReadWrite, raw_image.PixelFormat);
data_out = rgb_image.LockBits(new Rectangle(0, 0, rgb_image.Width, rgb_image.Height), ImageLockMode.ReadWrite, rgb_image.PixelFormat);
try
{
DecodeImageRaw(raw_image.Width, raw_image.Height, data_in.Scan0, data_out.Scan0);
return rgb_image;
}
finally
{
raw_image.UnlockBits(data_in);
rgb_image.UnlockBits(data_out);
}
}
Here DecodeImageRaw
is a method that uses the camera lib to decode the image. The above works fine for us.
The new version of the same code that uses windows imaging component:
public static BitmapSource DecodeImage(BitmapSource raw_image)
{
if (raw_image == null || raw_image.Format != PixelFormats.Indexed8)
return null;
var w = raw_image.PixelWidth;
var h = raw_image.PixelHeight;
var dx = raw_image.DpiX;
var dy = raw_image.DpiY;
var in_image = new WriteableBitmap(w, h, dx, dy, PixelFormats.Indexed8, raw_image.Palette);
var out_image = new WriteableBitmap(w, h, dx, dy, PixelFormats.Rgb24, null);
in_image.Lock();
out_image.Lock();
var bufin = in_image.BackBuffer;
var bufout = out_image.BackBuffer;
var s = in_image.BackBufferStride;
try
{
raw_image.CopyPixels(Int32Rect.Empty, bufin, h*s, s);
out_image.AddDirtyRect(new Int32Rect(0, 0, w, h));
DecodeImageRaw(w, h, bufin, bufout);
return out_image;
}
finally
{
in_image.Unlock();
out_image.Unlock();
}
}
The above actually outputs a image with the same shape, but the color is wrong (for example, the background should be "blue" for the sky, but it becomes brown.
So what is wrong with the new code? How to make it equivalent with the original one? Also I want to know explanation of the reason.
The decoded image should look like this
But it was decoded with the new code like this
EDIT
There are some little adjustment since the first edit to the code to make it easier to read and rule out some unrelated detail. For example, there was a bool
flag to select between algorithms, but was removed now. However, the behavior remains the same.