I know that the question has already been given, but here is my 2c ...
The following code comes from the PNGComponents package (PngFunctions.pas) created by Thany.
// //The Following code comes from the PNGComponents package from Thany... // procedure MakeImageGrayscale(Image: TPNGObject; Amount: Byte = 255); procedure GrayscaleRGB(var R, G, B: Byte); var X: Byte; begin X := Round(R * 0.30 + G * 0.59 + B * 0.11); R := Round(R / 256 * (256 - Amount - 1)) + Round(X / 256 * (Amount + 1)); G := Round(G / 256 * (256 - Amount - 1)) + Round(X / 256 * (Amount + 1)); B := Round(B / 256 * (256 - Amount - 1)) + Round(X / 256 * (Amount + 1)); end; var X, Y, PalCount: Integer; Line: Pointer; PaletteHandle: HPalette; Palette: array[Byte] of TPaletteEntry; begin //Don't do anything if the image is already a grayscaled one if not (Image.Header.ColorType in [COLOR_GRAYSCALE, COLOR_GRAYSCALEALPHA]) then begin if Image.Header.ColorType = COLOR_PALETTE then begin //Grayscale every palette entry PaletteHandle := Image.Palette; PalCount := GetPaletteEntries(PaletteHandle, 0, 256, Palette); for X := 0 to PalCount - 1 do GrayscaleRGB(Palette[X].peRed, Palette[X].peGreen, Palette[X].peBlue); SetPaletteEntries(PaletteHandle, 0, PalCount, Palette); Image.Palette := PaletteHandle; end else begin //Grayscale every pixel for Y := 0 to Image.Height - 1 do begin Line := Image.Scanline[Y]; for X := 0 to Image.Width - 1 do GrayscaleRGB(PRGBLine(Line)^[X].rgbtRed, PRGBLine(Line)^[X].rgbtGreen, PRGBLine(Line)^[X].rgbtBlue); end; end; end; end;
There is a set of routines that were originally published by the author of the PNGImage components, which can be found in Code Central, which shows how to do other things like Alpha, blend two images, rotate, overlay, etc. CodeCentral Link
source share