How to darken/enlight a TColor on run-time lazarus / 39-Graphics ---------------------------------------------------------------------- Raul_ES · 2020-06-11 22:19 Hello, I was wondering how to get a color from the palette like clForm or clGray and darken it in run-time, for example a 5% or 12%. And the opposite, to enlight the color a 20% for example. Let's say that I have certains controls that I want them to be a little bit more darker than the parent form color. regards ---------------------------------------------------------------------- Blaazen · 2020-06-11 23:19 The simpliest way is to use unit GraphUtil which has three functions: 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  function ColorAdjustLuma(clrRGB: TColor; n: Integer; fScale: BOOL): TColor; function GetHighLightColor(const Color: TColor; Luminance: Integer = 19): TColor; function GetShadowColor(const Color: TColor; Luminance: Integer = -50): TColor; ---------------------------------------------------------------------- Raul_ES · 2020-06-11 23:53 Thanks! ---------------------------------------------------------------------- circular · 2020-06-12 08:33 Note that you may need to call ColorToRGB with the system color to get an actual color. ---------------------------------------------------------------------- flowCRANE · 2020-06-12 15:01 Below are two procedures that I use to darken or lighten entire 24-bit bitmaps in the Deep Platformer project. They are very effective due to the use of ScanLine. If you are not interested in modifying the brightness of the whole bitmap, focus on three lines performing calculations (I highlighted them). The second parameter is the level of dimming/lightening, which can have a value from 0 to 255. 0 means that nothing will be changed, and 255 means full darkening or brightening. So the higher the value of this parameter, the stronger the change. 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 type  TBitmapPixel = record    B, G, R: UInt8;  end; type  PBitmapLine = ^TBitmapLine;  TBitmapLine = array [UInt16] of TBitmapPixel;  procedure DarkenBuffer(ABuffer: TBitmap; ALevel: UInt8);var  Line: PBitmapLine;  LineIndex, PixelIndex: Integer;begin  ALevel := 255 - ALevel;  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        B := B * ALevel shr 8;        G := G * ALevel shr 8;        R := R * ALevel shr 8;      end;  end;   ABuffer.EndUpdate();end;  procedure LightenBuffer(ABuffer: TBitmap; ALevel: UInt8);var  Line: PBitmapLine;  LineIndex, PixelIndex: Integer;begin  ALevel := 255 - ALevel;  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        B := Round(B * ALevel / 255 + 255 - ALevel);      G := Round(G * ALevel / 255 + 255 - ALevel);        R := Round(R * ALevel / 255 + 255 - ALevel);      end;  end;   ABuffer.EndUpdate();end; If you are interested in the percentage mixing of two colors, below is a simple procedure for doing this task. The parameter determining the level of mixing is the percentage, i.e. a value from 0 to 100: 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 type  TRGBTriple = packed record    B, G, R: UInt8;  end; function CombineColors(AColorA, AColorB: TColor; APercent: UInt8): TColor;var  ColorA, ColorB, ColorDest: TRGBTriple;begin  RedGreenBlue(AColorA, ColorA.R, ColorA.G, ColorA.B);  RedGreenBlue(AColorB, ColorB.R, ColorB.G, ColorB.B);   ColorDest.R := Round(ColorA.R + (ColorB.R - ColorA.R) / 100 * APercent);  ColorDest.G := Round(ColorA.G + (ColorB.G - ColorA.G) / 100 * APercent);  ColorDest.B := Round(ColorA.B + (ColorB.B - ColorA.B) / 100 * APercent);   Result := RGBToColor(ColorDest.R, ColorDest.G, ColorDest.B);end; This algorithm is useful — with it you can combine two images and create a smooth transition between them: 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 CombineImages(AImageA, AImageB, AImageDest: TPortableNetworkGraphic; ALevel, AScale: UInt8);type  PPNGPixel = ^TPNGPixel;  TPNGPixel = record B, G, R, A: UInt8; end;type  PPNGLine = ^TPNGLine;  TPNGLine = array [UInt16] of TPNGPixel;var  LineA, LineB, LineDest: PPNGLine;  PixelA, PixelB, PixelDest: PPNGPixel;var  LineIndex, PixelIndex: Integer;begin  AImageDest.BeginUpdate();  try    for LineIndex := 0 to AImageA.Height - 1 do    begin      LineA := AImageA.ScanLine[LineIndex];      LineB := AImageB.ScanLine[LineIndex];      LineDest := AImageDest.ScanLine[LineIndex];       for PixelIndex := 0 to AImageA.Width - 1 do      begin        PixelA := @LineA^[PixelIndex];        PixelB := @LineB^[PixelIndex];        PixelDest := @LineDest^[PixelIndex];         PixelDest^.R := Round(PixelA^.R + (PixelB^.R - PixelA^.R) / AScale * ALevel);        PixelDest^.G := Round(PixelA^.G + (PixelB^.G - PixelA^.G) / AScale * ALevel);        PixelDest^.B := Round(PixelA^.B + (PixelB^.B - PixelA^.B) / AScale * ALevel);      end;    end;  finally    AImageDest.EndUpdate();  end;end; This time the procedure operates on 24-bit PNG images, but nothing prevents you from adding alpha channel support or bitmap support. The first two parameters are source images, the third parameter is the target image. The AScale parameter determines the sensitivity and can have a value e.g. 100 (percentage mixing) or another value, e.g. 255. The ALevel parameter specifies the level of color mixing and must be between 0 and AScale. The higher the AScale value, the more levels of color mixing available. To the attachments I add the sources of both small tools, which I created a long time ago to test the above two algorithms (used on Windows). Feel free to use them. ---------------------------------------------------------------------- Raul_ES · 2020-06-15 11:08 Thank you very much for your help. regards