Grayscale lazarus / 39-Graphics ---------------------------------------------------------------------- pcurtis · 2020-06-09 07:18 How can I convert a colour image into grayscale? P.S. I dont want to use external tools. Thanks in advance. ---------------------------------------------------------------------- eljo · 2020-06-09 07:36 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses    Graphics, GraphUtiuls, .....; procedure ToGrayscale(const aBMP:TBitmap);var  X, Y: Integer;begin   For X :=0 to aBMP.Width -1 do    For Y := 0 to aBmp.Height -1 do begin      aBmp.Canvas.Pixels[X,Y] :=  ColorToGray(aBmp.Canvas.Pixels[X,Y]);    End;end;  Warning the above code is just a hint. It has never been compiled or checked for errors and of course this is not a recommendation on how to do it. In fact I would suggest to avoid the pixels property at all costs. ---------------------------------------------------------------------- pcurtis · 2020-06-09 07:44 Cant it be be done in one operation? ---------------------------------------------------------------------- eljo · 2020-06-09 07:55 Quote from: pcurtis on June 09, 2020, 09:44:18 amCant it be be done in one operation? no. an image is a collection of pixels you need to convert each pixel individually. ---------------------------------------------------------------------- circular · 2020-06-09 08:14 With BGRABitmap you can with the InplaceGrayscale function. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i image := TBGRABitmap.Create('image.png');image.InplaceGrayscale(True); //with gamma correction ---------------------------------------------------------------------- wp · 2020-06-09 08:29 Quote from: eljo on June 09, 2020, 09:36:42 amIn fact I would suggest to avoid the pixels property at all costs. Yes, the Pixels property is very slow. This is a faster version using LazIntfImage: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  LCLType, FPImage, IntfGraphics; procedure ToGrayscale(const ABitmap: TBitmap);var  img: TLazIntfImage;  i, j: Integer;  clr: TFPColor;  gray: Word;  bmpHandle, maskHandle: HBitmap;begin  img := ABitmap.CreateIntfImage;  for j := 0 to img.Height - 1 do    for i := 0 to img.Width - 1 do    begin      clr := img.Colors[i, j];      gray := (clr.Red + clr.Green + clr.Blue) div 3;      clr.Red := gray;      clr.Green := gray;      clr.Blue := gray;      img.Colors[i, j] := clr;    end;  img.CreateBitmaps(bmpHandle, maskHandle);  ABitmap.Handle := bmpHandle;  ABitmap.MaskHandle := maskHandle;end; ---------------------------------------------------------------------- pcurtis · 2020-06-09 08:43 @Circular - Thanks, its simple and works. @wp, I'll have a look later ---------------------------------------------------------------------- PaulRowntree · 2020-06-09 17:43 If you are trying to maintain visual comparisons, the three colour components are usually not equally weighted. https://en.wikipedia.org/wiki/Grayscale ---------------------------------------------------------------------- flowCRANE · 2020-06-15 18:47 Fastest way, no external libraries needed, no temporary image needed, good final quality: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure GrayBuffer(ABuffer: TBitmap);type  TBitmapPixel = record B, G, R: UInt8 end; type  PBitmapLine = ^TBitmapLine;  TBitmapLine = array [UInt16] of TBitmapPixel;var  Line: PBitmapLine;  LineIndex, PixelIndex: Integer;  GrayShade: UInt8;begin  ABuffer.BeginUpdate();   for LineIndex := 0 to ABuffer.Height - 1 do  begin    Line := ABuffer.ScanLine[LineIndex];     for PixelIndex := 0 to ABuffer.Width - 1 do      with Line^[PixelIndex] do      begin        GrayShade := Round(0.299 * R + 0.587 * G + 0.114 * B);              B := GrayShade;        G := GrayShade;        R := GrayShade;      end;  end;   ABuffer.EndUpdate();end;