Converting Bitmap Pixelformats in C#

Converting Bitmap PixelFormats in C#

Sloppy, not uncommon for GDI+. This fixes it:

Bitmap orig = new Bitmap(@"c:\temp\24bpp.bmp");
Bitmap clone = new Bitmap(orig.Width, orig.Height,
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);

using (Graphics gr = Graphics.FromImage(clone)) {
gr.DrawImage(orig, new Rectangle(0, 0, clone.Width, clone.Height));
}

// Dispose orig as necessary...

Convert from one PixelFormat to an other WPF

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.

Converting to indexed Bitmap PixelFormat in C#

This worked great and fast for me using P/Invoke to let GDI handle it (it can do the job, but the .Net API doesn't expose it for some weird reasons).

convert into 8bbp pixel format

Try this:

Point originPoint = new Point(0,0);
Rectangle rect = new Rectangle(originPoint, pictureBox.Image.Size);
Bitmap bitImage = (Bitmap)pictureBox.Image;
Bitmap formattedImage = bitImage.Clone(rect, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
pictureBox.Image = formattedImage;

The formmattedImage object contains what you're looking for, I'm putting it back into the System.Windows.Forms.PictureBox object I have on my form just to make it easier to see.

C# Resizing Bitmap without changing the Pixelformat


   Bitmap scaled = new Bitmap(origin, size);

There are a lot of implicit assumptions built into that constructor call. You'll get:

  • A bitmap with the 32bppPArgb pixel format. Meant to help the programmer fall into the pit of success, it is the most optimal pixel format on modern PCs. Compatible with the pixel format of the video adapter frame buffer, it can be blitted without any conversion. It is ten times faster than all the other ones.
  • The resolution is set to the video adapter DPI. This is usually a bit less optimal although it is pretty hard to argue that it should use the resolution of the source image after rescaling it. You might want to modify that.
  • A transparent background. That matters if the source bitmap has transparency or has pixels with the alpha channel set to a value < 255. Usually fine, if the source bitmap was transparent then the new one will be as well. Not so fine with alpha, rescaling the bitmap is pretty likely to affect that negatively. YMMV.
  • Bilinear interpolation of the source image. That is fairly modest, you might favor InterpolationMode.HighQualityBicubic for a better result, especially when you shrink it by more than 50%. Or NearestNeighbor if speed is your concern or the source image is very small and you enlarge it with the intention to keep the pixels visible as-is.

Clearly you are unhappy, the first bullet is the source of your complaint. Writing it out with all details tweakable:

    public static Bitmap RescaleImage(Image source, Size size) {
// 1st bullet, pixel format
var bmp = new Bitmap(size.Width, size.Height, source.PixelFormat);
// 2nd bullet, resolution
bmp.SetResolution(source.HorizontalResolution, source.VerticalResolution);
using (var gr = Graphics.FromImage(bmp)) {
// 3rd bullet, background
gr.Clear(Color.Transparent);
// 4th bullet, interpolation
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gr.DrawImage(source, new Rectangle(0, 0, size.Width, size.Height));
}
return bmp;
}
    -

Bitmap deep copy changing PixelFormat

You can clone the bitmap like this, which will create a deep copy:

Bitmap img = new Bitmap("C:\\temp\\images\\file.jpg");

// Clone the bitmap.
Rectangle cloneRect = new Rectangle(0, 0, img.Width, img.Height);
System.Drawing.Imaging.PixelFormat format =
img.PixelFormat;
Bitmap img2 = img.Clone(cloneRect, format);


Related Topics



Leave a reply



Submit