我正试图在我们的一个内部组件中实现一个分层绘画系统,我在混合包含文本的位图时遇到了问题.
uses GR32; procedure DrawBitmaps; var bmp1: TBitmap32; bmp2: TBitmap32; begin bmp1 := TBitmap32.Create; bmp1.Width := 100; bmp1.Height := 100; bmp1.FillRect(0,100,clWhite32); bmp1.FillRect(0,80,clTrGreen32); bmp1.Font.Size := -16; bmp1.Font.Color := clBlack; bmp1.textout(2,10,'Green'); bmp1.SavetoFile('c:\0\bmp1.bmp'); bmp2 := TBitmap32.Create; bmp2.Width := 80; bmp2.Height := 80; bmp2.FillRect(0,clTrRed32); bmp2.Font.Size := -16; bmp2.Font.Color := clBlack; bmp2.textout(2,50,'Red'); bmp2.SavetoFile('c:\0\bmp2.bmp'); bmp2.DrawMode := dmBlend; bmp2.DrawTo(bmp1,20,20); bmp1.SavetoFile('c:\0\bmpcombined.bmp'); bmp1.Free; bmp2.Free; end;
结果图像:
如您所见,文本在bmp和bmp2上涂成黑色,但在bmpcombined上显示为白色.
我猜测问题出在textout上,它映射到Windows.Exttextout(通过GR32_Backends_VCL.pas,TGDIBackend.textout).该方法不处理透明度并使用alpha 00绘制文本(颜色为$000000而不是$FF000000).
作为快速修复,将bmp2.Font.Color设置为$FF000000无济于事.
bmp2.Font.Color := TColor(clBlack32);
我正在使用GitHub的新资料
我应该如何在半透明背景上绘制不透明的文本,以便将其混合成更大的图片?
解决方法
据我所知,textout函数只是将一些文本添加到位图的直接方式,缺少上面提到的所有修复.
为了保持对透明度的完全控制,您可能希望使用
procedure TBitmap32.RenderText(X,Y: Integer; const Text: string; AALevel: Integer; Color: TColor32);
代替.
它使用您在自己的答案中提到的技术,但是在更复杂的层面上.它还允许您使用抗锯齿(基于过采样),但今天实际上并不建议使用除字体引擎输出之外的任何其他抗锯齿技术(以充分利用字体提示).
在使用最新的源代码时,您还可以考虑使用VPR来呈现文本(请参阅示例“TextVPR”).它将文本轮廓转换为矢量,并使用Graphics32的矢量绘图功能(默认使用引擎’VPR’,因此使用名称)将其渲染到屏幕上.还有一个包含AGG的精简引擎,它本身基于FreeType1引擎,对于字体来说可能略快一些.
说到性能:请记住,除textout之外的所有其他方法都会明显降低性能.因此,如果您的目标是高性能,可以更好地烹饪您自己的代码(基于textout).
否则,TextVPR方法会给您更多的自由,特别是在填充文本(例如使用渐变)或转换文本(转换为曲线等)时.