我们有一些实际上采用RAW
格式的位图图像,但它使用的是Windows位图格式,但是如果不使用提供的lib相机对其进行解码,则无法获得良好的结果。
以下是可以正常运行的代码:
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);
}
}
此处DecodeImageRaw
是一种使用相机lib解码图像的方法。以上工作对我们来说很好。
使用Windows映像组件的相同代码的新版本:
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();
}
}
以上实际上输出的图像形状相同,但颜色不对(例如,背景应为"蓝色"对于天空,但它会变成棕色。
那么新代码有什么问题?如何使它与原来的相同?另外我想知道原因的解释。
解码后的图像应如下所示
但它是用这样的新代码解码的
修改
自第一次编辑代码以来,有一些小的调整,以便更容易阅读和排除一些不相关的细节。例如,在算法之间有一个bool
标志可供选择,但现在已被删除。但是,行为保持不变。
答案 0 :(得分:2)
您有向后的频道:RGB
与BGR
。
我认出了这种效果。为了确认它,我在Photoshop中打开了解码图像,并手动交换了红色和蓝色频道。然后我得到了你期望的图像(无论是什么地狱):
我不理解您的代码,但请尝试PixelFormats.Bgr24
,而不是 PixelFormats.Rgb24 。