i'm trying to edit the pixels of a 8bpp. Since this PixelFormat
is indexed
i'm aware that it uses a Color Table to map the pixel values.
Even though I can edit the bitmap by converting it to 24bpp, 8bpp editing is much faster (13ms vs 3ms). But, changing each value when accessing the 8bpp bitmap results in some random rgb colors even though the PixelFormat remains 8bpp.
I'm currently developing in C# and the algorithm is as follows:
Scan0
of each BitmapData
object. (I used a C++ method as it offers better performance when iterating through the Bitmap's pixels)int[256]
palette according to some parameters and edit the temp bitmap bytes by passing the original's pixel values through the palette.My question is how can I edit the pixel values without having the strange rgb colors. Or, even better, how can I edit the 8bpp bitmap's Color Table?
There is no need to move into C++ land or use P/Invoke at all; C# supports pointers and unsafe code perfectly fine; I may even hazard a guess that this is causing your problems.
The colors are likely coming from the default Palette. You'll find that changing the Palette shouldn't be slow at all. This is what I do to create a greyscale palette:
image = new Bitmap( _size.Width, _size.Height, PixelFormat.Format8bppIndexed);
ColorPalette pal = image.Palette;
for(int i=0;i<=255;i++) {
// create greyscale color table
pal.Entries[i] = Color.FromArgb(i, i, i);
}
image.Palette = pal; // you need to re-set this property to force the new ColorPalette
Imagine that your indexed 8ppp graysacle are stored in a linear array dataB (for speed)
Try this code:
//Create 8bpp bitmap and look bitmap data
bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
bmp.SetResolution(horizontalResolution, verticalResolution);
bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
//Create grayscale color table
ColorPalette palette = bmp.Palette;
for (int i = 0; i < 256; i++)
palette.Entries[i] = Color.FromArgb(i, i, i);
bmp.Palette = palette;
//write data to bitmap
int dataCount = 0;
int stride = bmpData.Stride < 0 ? -bmpData.Stride : bmpData.Stride;
unsafe
{
byte* row = (byte*)bmpData.Scan0;
for (int f = 0; f < height; f++)
{
for (int w = 0; w < width; w++)
{
row[w] = (byte)Math.Min(255, Math.Max(0, dataB[dataCount]));
dataCount++;
}
row += stride;
}
}
//Unlock bitmap data
bmp.UnlockBits(bmpData);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With