Okay, I did it — huge thanks to
@Handoko for guiding me.
I checked the image class code carefully. First, set
UsePalette to
True so that the internal palette object is created in the image class:
BitmapImage := TFPMemoryImage.Create(100, 100);
BitmapImage.UsePalette := True;
Then fill the palette with used colors (and remember that the color components are 16-bit wide!):
BitmapImage.Palette.Color[0] := FPColor($FFFF, $0000, $FFFF); // fuchsia
BitmapImage.Palette.Color[1] := FPColor($0000, $0000, $0000); // black
While painting, we can pick colors directly from the palette:
BitmapCanvas.Brush.FPColor := BitmapImage.Palette.Color[0];
BitmapCanvas.FillRect(BitmapCanvas.ClipRect);
BitmapCanvas.Brush.FPColor := BitmapImage.Palette.Color[1];
BitmapCanvas.FillRect(20, 20, 50, 50);
The full example below:
var
BitmapImage: TFPMemoryImage;
BitmapCanvas: TFPImageCanvas;
BitmapWriter: TFPWriterBMP;
begin
BitmapImage := TFPMemoryImage.Create(100, 100);
BitmapImage.UsePalette := True;
BitmapImage.Palette.Color[0] := FPColor($FFFF, $0000, $FFFF);
BitmapImage.Palette.Color[1] := FPColor($0000, $0000, $0000);
BitmapCanvas := TFPImageCanvas.Create(BitmapImage);
BitmapCanvas.Brush.FPColor := BitmapImage.Palette.Color[0];
BitmapCanvas.FillRect(BitmapCanvas.ClipRect);
BitmapCanvas.Brush.FPColor := BitmapImage.Palette.Color[1];
BitmapCanvas.FillRect(20, 20, 50, 50);
BitmapWriter := TFPWriterBMP.Create();
BitmapWriter.BitsPerPixel := 4;
BitmapImage.SaveToFile('standard.bmp', BitmapWriter);
BitmapCanvas.Free();
BitmapImage.Free();
BitmapWriter.Free();
end;
In addition, if the bitmap has large, one-color areas (as in my case), it is worth using
RLE compression (the file size will be much smaller):
BitmapWriter := TFPWriterBMP.Create();
BitmapWriter.BitsPerPixel := 4;
BitmapWriter.RLECompress := True;
I add sample files to attachments.