delphi – 如何在透明度和不透明度的画布上绘画?

前端之家收集整理的这篇文章主要介绍了delphi – 如何在透明度和不透明度的画布上绘画?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
概观

从GR32库,我使用TImgView32渲染一个网格,这将是我的透明背景,如下所示:

放在TImgView32里面,我有一个常规的TImage,我将在画布上绘制,像这样:

任务

我想要实现的是设置画笔的不透明度的能力,允许在我的程序中进一步的图像编辑的可能性.不是画一个平面颜色,而是设置画笔的不透明度可以让不同颜色的深度等级

我早些时候发现了这个问题:Draw opacity ellipse in Delphi 2010 – Andreas Rejbrand在他的答案中提供了一些例子.

我看过安德烈亚斯做了什么,想出了自己的简单尝试,但是我遇到了一个问题.看看下面这两个图像,第一个是透明背景,第二个是黑色背景,使问题更加清晰:

你可以看到,在刷子(圆圈)周围是一个非常烦人的广场,我无法摆脱.所有应该可见的是刷子.这是我用来产生这些结果的代码

procedure DrawOpacityBrush(ACanvasBitmap: TBitmap; X,Y: Integer;
  AColor: TColor; ASize: Integer; Opacity: Integer);
var
  Bmp: TBitmap;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.SetSize(ASize,ASize);
    Bmp.Transparent := False;

    with Bmp.Canvas do
    begin
      Pen.Color := AColor;
      Pen.Style := psSolid;
      Pen.Width := ASize;
      MoveTo(ASize div 2,ASize div 2);
      LineTo(ASize div 2,ASize div 2);
    end;

    ACanvasBitmap.Canvas.Draw(X,Y,Bmp,Opacity);
  finally
    Bmp.Free;
  end;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X,Y: Integer);
begin
  DrawOpacityBrush(Image1.Picture.Bitmap,X,clRed,50,85);
end;

它通过一个常规的位图产生:

我的想法(基于Andreas创建具有不透明度的椭圆形)的方法是在画布上渲染一个典型的画笔,将其分配给一个屏幕外的位图,然后用不透明度将其重新绘制到主要的位图上.哪个工作,除了令人讨厌的正方形围绕边缘.

如何在屏幕截图中显示不透明度的画笔,但是画笔圈周围没有这个方格?

如果我设置Bmp.Transparent:= True,仍然是一个白色框,但没有不透明度了.只是一个坚实的白色方块和坚实的红色圆圈.

解决方法

TCanvas.Draw()的不透明度功能不支持您尝试执行的操作,至少不是您尝试使用它的方式.要完成您想要的影响,您需要创建一个32位TBitmap,以便您具有每像素Alpha通道,然后填充每个像素的Alpha,将alpha设置为0,以便您不需要像素,并设置您想要的像素的所需不透明度的alpha.然后,当调用TCanvas.Draw()时,将其不透明度设置为255,以使其仅使用每像素不透明度.
procedure DrawOpacityBrush(ACanvas: TCanvas; X,Y: Integer; AColor: TColor; ASize: Integer; Opacity: Byte);
var
  Bmp: TBitmap;
  I,J: Integer;
  Pixels: PRGBQuad;
  ColorRgb: Integer;
  ColorR,ColorG,ColorB: Byte;
begin
  Bmp := TBitmap.Create;
  try
    Bmp.PixelFormat := pf32Bit; // needed for an alpha channel
    Bmp.SetSize(ASize,ASize);

    with Bmp.Canvas do
    begin
      Brush.Color := clFuchsia; // background color to mask out
      ColorRgb := ColorToRGB(Brush.Color);
      FillRect(Rect(0,ASize,ASize));
      Pen.Color := AColor;
      Pen.Style := psSolid;
      Pen.Width := ASize;
      MoveTo(ASize div 2,ASize div 2);
    end;

    ColorR := GetRValue(ColorRgb);
    ColorG := GetGValue(ColorRgb);
    ColorB := GetBValue(ColorRgb);

    for I := 0 to Bmp.Height-1 do
    begin
      Pixels := PRGBQuad(Bmp.ScanLine[I]);
      for J := 0 to Bmp.Width-1 do
      begin
        with Pixels^ do
        begin
          if (rgbRed = ColorR) and (rgbGreen = ColorG) and (rgbBlue = ColorB) then
            rgbReserved := 0
          else
            rgbReserved := Opacity; 
          // must pre-multiply the pixel with its alpha channel before drawing
          rgbRed := (rgbRed * rgbReserved) div $FF;
          rgbGreen := (rgbGreen * rgbReserved) div $FF;
          rgbBlue := (rgbBlue * rgbReserved) div $FF;
        end;
        Inc(Pixels);
      end;
    end;

    ACanvas.Draw(X,255);
  finally
    Bmp.Free;
  end;
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;  
  Shift: TShiftState; X,Y: Integer);  
begin  
  DrawOpacityBrush(Image1.Picture.Bitmap.Canvas,85);  
end;
原文链接:https://www.f2er.com/delphi/101445.html

猜你在找的Delphi相关文章