question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add support for converting the format of a Bitmap

See original GitHub issue

Background

GDI+ 1.1 added support for converting the pixel format of an bitmap in-place. Naturally, one can specify a target pixel format, but the function accepts many other parameters to control aspects of the conversion. Unfortunately, the API is not very well designed — it’s poorly documented, and many combinations of options seem to be outright ignored or result in vague errors — but a not insubstantial amount of people have wondered how to do this, and the workaround is slow, less flexible, and certainly not obvious.

When converting to an indexed pixel format, the ditherType, paletteType, and palette parameters become relevant. Color palettes can be provided in order to constrain the colors in the converted image. There are effectively three categories of palettes:

  • Custom palettes. All available colors are specified by the user.
  • Optimal palettes. An optimal palette is created using an image, and consists of the best n colors (where n is specified by the user) from the image to be used when converting the image.
  • Standard palettes. The user can specify one of many predefined fixed palettes, and may use them in combination with an ordered or spiral dither type to produce a halftone image.

When a standard fixed palette type is used, any dither type is valid. Otherwise, only None, Solid, and ErrorDiffusion are valid. (As an exception, DitherTypeOrdered4x4 may be used when converting to a 16 bits-per-pixel format using any palette.) GDI+ will convert from a standard palette specified with paletteType to a custom palette passed in palette using a nearest-color conversion.

One can also specify an alpha threshold percent. Passing a value t specifies that a pixel that is less than t percent fully opaque will map to the transparent color. (If there is no transparent color, the color closest to black will be selected.)

This proposal is one of many to add missing GDI+ 1.1 functionality to System.Drawing.

Usage Example

Bitmap bitmap = (Bitmap) Image.FromFile("immo.jpg");
ColorPalette palette = new ColorPalette(PaletteType.FixedHalftone8);
image.ConvertFormat(PixelFormat.Format8bppIndexed, DitherType.Ordered16x16, PaletteType.FixedHalftone8, palette);

Before and after sample of above code sample

API Proposal

See the documentation for:

namespace System.Drawing.Imaging
{
+   public enum PaletteType
+   {
+       Custom,
+       Optimal,
+       FixedBW,
+       FixedHalftone8,
+       FixedHalftone27,
+       FixedHalftone64,
+       FixedHalftone125,
+       FixedHalftone216,
+       FixedHalftone252,
+       FixedHalftone256
+   }
    
+   public enum DitherType
+   {
+       None,
+       Solid,
+       ErrorDiffusion,
+       Ordered4x4,
+       Ordered8x8,
+       Ordered16x16,
+       Spiral4x4,
+       Spiral8x8,
+       DualSpiral4x4,
+       DualSpiral8x8
+   }

    public sealed class ColorPalette
    {
+       public ColorPalette(Color[] customColors);
+       public ColorPalette(PaletteType fixedPaletteType);
+       public static ColorPalette CreateOptimalPalette(int colors, Bitmap bitmap);
    }
}

namespace System.Drawing
{
    public sealed class Bitmap : System.Drawing.Image
    {
!       Overload for simplicity.
+       public void ConvertFormat(PixelFormat format);
+       public void ConvertFormat(PixelFormat format, DitherType ditherType, PaletteType paletteType, ColorPalette? palette, float alphaThresholdPercent);
    }
}

This requires changes to libgdiplus in order to support it on non-Windows platforms.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:17
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

4reactions
reflectroniccommented, Apr 8, 2021

What would the story for Unix be?

Setting myself up for a lot of work to contribute to libgdiplus 😃

2reactions
saferncommented, Jul 16, 2021

Thanks, @reflectronic. Sure I will. I will mark these issues 7.0.0 for now so that we review them for .NET 7.

Read more comments on GitHub >

github_iconTop Results From Across the Web

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.
Read more >
Bitmap::ConvertFormat (gdiplusheaders.h) - Win32 apps
The Bitmap::ConvertFormat method converts a bitmap to a specified pixel format. The original pixel data in the bitmap is replaced by the new ......
Read more >
How to: Convert a BMP image to a PNG image - Windows ...
You can do this conversion easily by calling the Save method of the Image class and specifying the ImageFormat for the desired image...
Read more >
[Solved] How to Convert Image to BMP File Format?
1. Firstly, install and launch this software on your operating system. · 2. Next, choose either File or Folder option in order to...
Read more >
ImageMagick – Convert, Edit, or Compose Digital Images
It can be used to create, edit, compose, or convert bitmap images, and supports a wide range of file formats, including JPEG, PNG,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found