Creating 8-bit images
Solution 1
Use this constructor to specify a pixel format : http://msdn.microsoft.com/en-us/library/3z132tat.aspx
Since you cannot create a Graphics from an indexed pixel format, you can only write raw pixels to a 8-bit image.
Bitmap bitmap = new Bitmap(32, 32, PixelFormat.Format8bppIndexed);
var bitmapData = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadWrite, bitmap.PixelFormat);
Random random=new Random();
byte[] buffer=new byte[bitmap.Width*bitmap.Height];
random.NextBytes(buffer);
Marshal.Copy(buffer,0,bitmapData.Scan0,buffer.Length);
bitmap.UnlockBits(bitmapData);
bitmap.Save("test.bmp",ImageFormat.Bmp);
You can either use such code on WinForms : http://www.codeproject.com/Articles/17162/Fast-Color-Depth-Change-for-Bitmaps
Or if you can reference this class from WPF it will be much easier : http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.formatconvertedbitmap(v=vs.85).aspx
Solution 2
You could also create the image at a higher bit rate and then convert it to 8 bits just before saving. This would allow you to use a Graphics context when creating the image. See this question for suggestions on how to convert to 8 bits:C# - How to convert an Image into an 8-bit color Image?
DigitalNomad
Updated on June 15, 2022Comments
-
DigitalNomad almost 2 years
I'm trying to create an 8-bit image with a solid background color. It seems like it should be pretty straight forward but the details on the file list it as 32-bit color depth. What am I missing?
public void CreateImage() { var bmpOut = new Bitmap(300, 300); var g = Graphics.FromImage(bmpOut); g.FillRectangle(new SolidBrush(Color.Gray), 0, 0, 300, 300); var stream = new MemoryStream(); bmpOut.Save(stream, GetPngCodecInfo(), GetEncoderParameters()); bmpOut.Save(@"C:\image.png", GetPngCodecInfo(), GetEncoderParameters()); } public EncoderParameters GetEncoderParameters() { var parameters = new EncoderParameters(); parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8); return parameters; } public ImageCodecInfo GetPngCodecInfo() { var encoders = ImageCodecInfo.GetImageEncoders(); ImageCodecInfo codecInfo = null; foreach (var imageCodecInfo in encoders) { if (imageCodecInfo.FormatID != ImageFormat.Png.Guid) continue; codecInfo = imageCodecInfo; break; } return codecInfo; }
-
Zach about 11 yearsBe careful, though. Specifying the pixel format alone will not be enough as creating an 8-bit indexed image will fail on the next line—creating a
Graphics
from the image. -
aybe about 11 yearsCreating a Graphics from an indexed format will raise an exception : A Graphics object cannot be created from an image that has an indexed pixel format.
-
Nyerguds about 7 yearsWhat on earth is that
Random
doing there? -
Lelo about 7 years@Nyerguds being used to create a random image, I supposed? As a matter of fact, I bumped into this answer looking for a way to visualize my random data
-
Nyerguds about 7 yearsThis answer doesn't actually answer the question, by the way. This does not in any way allow a user to determine how to select and paint a specific color. To do that, you need to edit the color palette. As far as I can see, the resulting random image from this just uses the colors of the default palette created with an 8-bit image.
-
Nyerguds about 7 yearsThere is no sense in converting a palette to grayscale for a new image. Just fill the palette with color values from 00,00,00 to FF,FF,FF. With a palette like that, you are 100% sure to have all gray values, and the 8-bit value to put on the final pixel is simply equal to any of the three color components of the actual grayscaled pixel colour. No more lookups needed.
-
Pablo Gonzalez over 5 years@Aybe So at the end, how can we get the 8bit bitmap after creating a graphics?