delphi – 创建透明的自定义位图画笔

前端之家收集整理的这篇文章主要介绍了delphi – 创建透明的自定义位图画笔前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题定义

我正在尝试创建一个具有透明度的自定义位图画笔,但它似乎没有按预期工作.如果你看一下这个例子.添加代码并连接绘制,创建和销毁事件.

  1. type
  2. TForm3 = class(TForm)
  3. procedure FormDestroy(Sender: TObject);
  4. procedure FormCreate(Sender: TObject);
  5. procedure FormPaint(Sender: TObject);
  6. private
  7. FBitmap: TBitmap;
  8. end;
  9.  
  10. // Implementation
  11.  
  12. function CreateBlockBitmap(const APenColor: TColor): TBitmap;
  13. begin
  14. Result := TBitmap.Create;
  15. Result.Transparent := True;
  16. Result.Canvas.Brush.Color := clWhite;
  17. Result.Canvas.Brush.Style := bsClear;
  18. Result.PixelFormat := pf32bit;
  19. Result.SetSize(20,20);
  20. Result.Canvas.Brush.Color := APenColor;
  21. Result.Canvas.Brush.Style := bsSolid;
  22. Result.Canvas.FillRect(Rect(0,10,10));
  23. end;
  24.  
  25. procedure TForm3.FormDestroy(Sender: TObject);
  26. begin
  27. FBitmap.Free;
  28. end;
  29.  
  30. procedure TForm3.FormCreate(Sender: TObject);
  31. begin
  32. FBitmap := CreateBlockBitmap(clRed);
  33. end;
  34.  
  35. procedure TForm3.FormPaint(Sender: TObject);
  36. var
  37. colNum: Integer;
  38. rowNum: Integer;
  39. begin
  40. // Paint the rectangle using the brush
  41. Canvas.Pen.Color := clGreen;
  42. Canvas.Brush.Bitmap := FBitmap; // This is using bitmap
  43. Canvas.Rectangle(50,50,250,250);
  44. // Draw the block using Canvas.Draw
  45. for rowNum := 0 to 9 do
  46. for colNum := 0 to 9 do
  47. Canvas.Draw(350 + rowNum * 20,50 + colNum * 20,FBitmap);
  48. end;

代码生成两个绘制的块.左边的一个使用位图画笔绘制,右边的一个使用Canvas.Draw调用绘制.

我需要刷涂上透明度,类似于使用舱口刷时会发生的情况.这个答案似乎表明它是可能的:

How can I draw a patternBrush with transparent backround (GDI)?

我试过的

1)我尝试使用纯色背景而不是使用bsClear.这只会使背景变白.

  1. Result.Canvas.Brush.Color := clWhite;
  2. Result.Canvas.Brush.Style := bsSolid;

如果我使用clFuchsia,那么颜色是紫红色.我也尝试绘制背景clFuchsia,然后将TransparentColor设置为clFuchsia. Canvas.Draw选项使用透明度绘制,而画笔则不绘制.

2)我尝试使用以下代码直接设置alpha通道:

  1. procedure SetAlphaBitmap(const Dest: TBitmap;Color : TColor;Alpha:Byte);
  2. type
  3. TRGB32 = record
  4. B,G,R,A: byte;
  5. end;
  6. PRGBArray32 = ^TRGBArray32;
  7. TRGBArray32 = array[0..0] of TRGB32;
  8. var
  9. x,y: integer;
  10. Line,Delta: integer;
  11. ColorRGB : TColor;
  12. begin
  13. if Dest.PixelFormat<>pf32bit then exit;
  14.  
  15. ColorRGB := ColorToRGB(Color);
  16. Line := integer(Dest.ScanLine[0]);
  17. Delta := integer(Dest.ScanLine[1]) - Line;
  18. for y := 0 to Dest.Height - 1 do
  19. begin
  20. for x := 0 to Dest.Width - 1 do
  21. if TColor(RGB(PRGBArray32(Line)[x].R,PRGBArray32(Line)[x].G,PRGBArray32(Line)[x].B)) = ColorRGB then
  22. PRGBArray32(Line)[x].A := Alpha;
  23. Inc(Line,Delta);
  24. end;
  25. end;

然后在使用背景颜色绘制矩形后立即调用此例程.

  1. Result.Canvas.Brush.Style := bsSolid;
  2. Result.Canvas.FillRect(Rect(0,10));
  3. SetAlphaBitmap(Result,clBlack,0); // Set the alpha channel
  4. end;

我知道alpha通道正在工作,因为如果我传入alpha值为255,那么它也会在Canvas.Draw中以黑色显示.

  1. SetAlphaBitmap(Result,255);

3)我尝试通过创建模式画笔并分配而不是位图来进行测试.这产生了完全相同的结果. FBrush是HBRUSH.

  1. FBrush := CreatePatternBrush(FBitmap.Handle);

并像这样设置画笔:

  1. Canvas.Brush.Handle := FBrush;

4)我尝试调用SetBkMode,如上面的SO答案中所示.这没有任何区别.

  1. Canvas.Pen.Color := clGreen;
  2. Canvas.Brush.Bitmap := FBitmap;
  3. SetBkMode(Canvas.Handle,TRANSPARENT); // This doesn't make a difference
  4. Canvas.Rectangle(50,250);

编辑

5)我刚用单色位图测试,它有同样的问题.图像涂有白色背景和黑色前景用于画笔,透明用于Canvas.Draw.

  1. function CreateMonochromeBitmap: TBitmap;
  2. begin
  3. Result := TBitmap.Create;
  4. Result.Transparent := True;
  5. Result.Canvas.Brush.Color := clWhite;
  6. Result.Canvas.Brush.Style := bsSolid;
  7. Result.PixelFormat := pf1bit;
  8. Result.SetSize(20,20);
  9. Result.Canvas.Brush.Color := clBlack;
  10. Result.Canvas.Brush.Style := bsSolid;
  11. Result.Canvas.FillRect(Rect(0,10));
  12. end;

在构造函数中:

  1. FBitmap := CreateMonochromeBitmap;
  2. FBrush := CreatePatternBrush(FBitmap.Handle);

在paint中我们设置句柄而不是位图属性.

  1. Canvas.Brush.Handle := FBrush;

解决方法

尝试在绘制循环之前清除画布此null颜色.

Canvas.Clear(TAlphaColorRec.Null);

问候.保罗.

猜你在找的Delphi相关文章