Search code examples
delphicolorsbitmapreductionquantization

How to reduce colors to a specified number in Delphi?


How can I reduce colors to a specified number (<=256) in Delphi? I don't want to just use:

 Bmp.PixelFormat := pf8bit;

because that way I cannot control number of colors. I don't want dithering, because I already know how to dither an image with 256 or less colors.

I found this Median Cut implementation but it is pure Pascal from 1990 and:

  1. doesn't compile in Delphi
  2. Says it's shareware and costs 25 Deutche Marks
  3. Looks (somehow) unnecessary complicated

I want to reduce TBitmap32 only (Graphics32 bitmap class, supports only 32bit colors) to <= 8bit bmp. I don't need to reduce to 15/16bit, I don't need to reduce from 24 or 15/16bit images. Just 32bit => 8bit-

Delphi I use: 7, 2005, XE3.


Solution

  • An fast implemented,cheap way with many options would be the usage of TGIFImage

    uses
      gifimg;
    
    
    
     Procedure ReduceTo8Bit(var bmp:TBitmap; ColorReduction: TColorReduction; DitherMode: TDitherMode);
    var
     GI:TGifImage;
    begin
       GI:=TGifImage.Create;
       try
         GI.DitherMode := DitherMode;
         GI.ColorReduction := ColorReduction;
         GI.Assign(bmp);
         bmp.Assign(GI.Bitmap);
       finally
         GI.Free;
       end;
    end;
    

    TEST

    procedure TForm3.Button2Click(Sender: TObject);
    var
     bmp:TBitmap;
    begin
      bmp:=TBitmap.Create;
      try
         bmp.LoadFromFile('C:\bilder\bummi.bmp');
         ReduceTo8Bit(bmp,rmQuantizeWindows,dmSierra);
         bmp.SaveToFile('C:\bilder\bummi_8bit.bmp');
      finally
        bmp.Free;
      end;
    end;
    

    a easier way will be using ReduceColors with rmQuantize from gifimg, if bits per pixel have to be set

    // BytesPerPixel integer with range of Range 3 - 8
    
    DestBMP := ReduceColors(SourceBMP,rmQuantize,dmNearest,BytesPerPixel,0);