I know this sounds trivial, but I currently have stuck.
I have images in various formats as input. Gray16,Gray8,Indexed8 and so on. What do I need is to covert them to RGB24 format, so far I've done this
public WriteableBitmap ConvertToRgb(WriteableBitmap source)
{
<-- create the new bitmap of the same width/height as the source with specific RGB24 format-->
var newBitmap = new WriteableBitmap(source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, PixelFormats.Rgb24, source.Palette);
<-- create my pixel array -->
byte[] pixels = new byte[
source.PixelHeight * source.PixelWidth *
source.Format.BitsPerPixel / 8];
<-- copy my original pixels into the array) -->
source.CopyPixels(pixels, source.PixelWidth * source.Format.BitsPerPixel / 8, 0);
<-- write the pixels into the new image -->
newBitmap.WritePixels(
new Int32Rect(0, 0, newBitmap.PixelWidth, newBitmap.PixelHeight),
pixels,
newBitmap.PixelWidth * newBitmap.Format.BitsPerPixel/8,
0);
return newBitmap;
}
This method throws an exception "Buffer size is not sufficient"
I guess it has to do something with one of my WritePixels parameters. But I have no idea what is the right size of the buffer. I couldn't find much documentation. Any help would be nice.
The method I'm using to convert is not definitive, if you know a better way of converting please let me know.
So after many attempts I found the answer.
public WriteableBitmap ConvertToRgb(WriteableBitmap source)
{
var newBitmap = new WriteableBitmap(source.PixelWidth, source.PixelHeight, source.DpiX, source.DpiY, PixelFormats.Rgb24, null);
byte[] pixels = new byte[
source.PixelHeight * source.PixelWidth *
source.Format.BitsPerPixel / 8];
source.CopyPixels(pixels, source.PixelWidth * source.Format.BitsPerPixel / 8, 0);
byte[] newPixels = new byte[newBitmap.PixelWidth * newBitmap.PixelHeight * newBitmap.Format.BitsPerPixel / 8];
var pixelCounter = 0;
var colorArray = source.Palette != null ? source.Palette.Colors.ToArray() : BitmapPalettes.Gray256.Colors.ToArray();
foreach (var pixel in pixels)
{
newPixels[pixelCounter] = colorArray[pixel].R;
pixelCounter++;
newPixels[pixelCounter] = colorArray[pixel].G;
pixelCounter++;
newPixels[pixelCounter] = colorArray[pixel].B;
pixelCounter++;
}
newBitmap.WritePixels(
new Int32Rect(0, 0, newBitmap.PixelWidth, newBitmap.PixelHeight),
newPixels,
newBitmap.PixelWidth * newBitmap.Format.BitsPerPixel / 8,
0);
return newBitmap;
}
Basically the problem was somwhere in the Stride I guess and the newPixel array dimensions. This is a fully working converting function.