[SOLVED] Need help drawing a rectangle with opacity. lazarus / 39-Graphics ---------------------------------------------------------------------- knuckles · 2016-05-16 21:05 I need to draw a rectangle that can have a opacity value from 0 to 100. The below snippet from Delphi Dabbler (http://delphidabbler.com/tips/203) works but is very slow with larger rectangles: 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 DrawTransparentRectangle(Canvas: TCanvas; Rect: TRect;  Color: TColor; Transparency: Integer);var  X: Integer;  Y: Integer;  C: TColor;  R, G, B: Integer;  RR, RG, RB: Integer;begin  RR := GetRValue(Color);  RG := GetGValue(Color);  RB := GetBValue(Color);   for Y := Rect.Top to Rect.Bottom - 1 do    for X := Rect.Left to Rect.Right - 1 do    begin      C := Canvas.Pixels[X, Y];      R := Round(        0.01 * (Transparency * GetRValue(C) + (100 - Transparency) * RR)      );     G := Round(        0.01 * (Transparency * GetGValue(C) + (100 - Transparency) * RG)      );       B := Round(        0.01 * (Transparency * GetBValue(C) + (100 - Transparency) * RB)      );     Canvas.Pixels[X, Y] := RGB(R, G, B);    end;end; I know the reason is because accessing pixels individually is a lot slower then using scanline but I am unsure how I exactly I could optimise the above. I thought maybe draw to a offscreen bitmap and use it's scanline but not exactly sure how I would go about that (the scanline part), I also need to make sure I can see through the opacity rectangle at whatever graphic is underneath on the canvas. Alternatively, Delphi has Windows.AlphaBlend which I believe could help me greatly but I couldn't find this in Lazarus. Can anyone advise how to write such a procedure to paint a rectangle with opacity that is not slow? I need to draw a overlay rectangle on top of a canvas, it doesn't even need to be based on the example above I just need a quick way of doing this without any 3rd party solution such as GR32 etc. Thanks. ---------------------------------------------------------------------- lainz · 2016-05-16 22:35 Try using BGRABitmap library. 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 TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);begin  Bitmap.Rectangle(x, y, x2, y2, BGRA(0,0,0,alpha), dmDrawWithTransparency);end; x, y, x2 and y2: here put your rect. BGRA function returns a color with alpha value. In this demo I'm also using BGRAControls BGRAVirtualScreen component that is a custom panel to draw into it. Or you can use just a TBGRABitmap object and then draw to your canvas instead. ---------------------------------------------------------------------- engkin · 2016-05-17 05:24 Quote from: knuckles on May 16, 2016, 11:05:25 pmAlternatively, Delphi has Windows.AlphaBlend which I believe could help me greatly but I couldn't find this in Lazarus. It is in unit JwaWindows. ---------------------------------------------------------------------- knuckles · 2016-05-17 10:33 Quote from: engkin on May 17, 2016, 07:24:07 amQuote from: knuckles on May 16, 2016, 11:05:25 pmAlternatively, Delphi has Windows.AlphaBlend which I believe could help me greatly but I couldn't find this in Lazarus. It is in unit JwaWindows. I should have mentioned I tried this, in fact I did a find in files on the lazarus directory for the keyword AlphaBlend, unfortunately by adding that unit it messes up my other graphics routines as things like TBitmap get confused with which unit to use. EDIT: Moved the unit to be the first in the uses clause and now works, will experiment with this now thanks. ---------------------------------------------------------------------- knuckles · 2016-05-17 10:37 Quote from: lainz on May 17, 2016, 12:35:45 amTry using BGRABitmap library. 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 TForm1.BGRAVirtualScreen1Redraw(Sender: TObject; Bitmap: TBGRABitmap);begin  Bitmap.Rectangle(x, y, x2, y2, BGRA(0,0,0,alpha), dmDrawWithTransparency);end; x, y, x2 and y2: here put your rect. BGRA function returns a color with alpha value. In this demo I'm also using BGRAControls BGRAVirtualScreen component that is a custom panel to draw into it. Or you can use just a TBGRABitmap object and then draw to your canvas instead. It does simplify things somewhat but at the moment for my purpose I need to avoid a 3rd party solution. Thanks though ---------------------------------------------------------------------- circular · 2016-05-17 20:27 Hmmm... it may be faster to use LazIntfImage as an intermediate where you do the blending and then draw it back on the canvas.