Reputation: 6605
I have a .NEF image. I installed the codec, then use below code to show it:
BitmapDecoder bmpDec = BitmapDecoder.Create(new Uri(@"C:\Temp\Img0926.nef"), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
BitmapSource srs = bmpDec.Frames[0];
this.imgDisplayed4.Source = srs;
this.imgDisplayed4.Stretch = Stretch.UniformToFill;
Then use below code to create the bmp and save it:
Bitmap bmp = new Bitmap(srs.PixelWidth, srs.PixelHeight, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
System.Drawing.Imaging.BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
srs.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
bmp.Save(@"C:\Temp\Images\Img0926-1.bmp");
It saves the bmp file, however, it seems the color in the bmp has some changes. I attached 3 screen shots. The 1st one is the saved bmp file shown by Windows Photo Viewer, the 2nd one is the original .NEF image, the 3rd one is the image shown in the image control.
We can see that they are all similar. However, the 2nd and 3rd ones have similar colors, and they are different from the 1st one.
I searched a lot and all I can find are similar to what I'm doing. However, they are all for Format32bppRgb. Could the issue is because the image I'm using is Format48bppRgb? Anyone have any idea? and how to fix this?
Thanks
Upvotes: 0
Views: 1027
Reputation: 6605
I realize the difference between 1st and 2nd images is: if we switch the color Red part and B part in the 1st image, then we get the 2nd image. So, I changed the code to:
System.Drawing.Imaging.BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
unsafe
{
srs.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
for (var row = 0; row < srs.PixelHeight; row++)
{
for (var col = 0; col < srs.PixelWidth; col++)
{
byte* pixel = (byte*)data.Scan0 + (row * data.Stride) + (col * 6);
var val1 = pixel[1];
var val3 = pixel[3];
var val2 = pixel[2];
var val4 = pixel[4];
var val5 = pixel[5];
var val0 = pixel[0];
//// 0, 1: B, 2:3: G, 4, 5: R
pixel[5] = val1;
pixel[4] = val0;
pixel[0] = val4;
pixel[1] = val5;
}
}
}
bmp.UnlockBits(data);
Now, the result is correct.
It seems there is a bug in BitmapSource.CopyPixels when the PixelFormat is Format48bppRgb. It copies the pixels in the order of BGR instead of RGB.
Anyone understands why I have to switch R & B part? Any other suggestions?
Anyway, it works fine now. It took me more than 10 hours to figure this out, someone else may need this in the future. Hope it helps.
thanks
Upvotes: 1