在 Canvas 上绘制,在 Firemonkey 中没有抗锯齿效果
Draw on Canvas with no anti-aliasing effect in Firemonkey
我正在尝试制作一种位图编辑器,所以我只想在位图上画一条线,在 Firemonkey 中没有抗锯齿效果。像这样:
var
Bmp: TBitmap;
Bmp := TBitmap.Create(2000, 2000);
if (Bmp.Canvas.BeginScene) then
begin
Bmp.Canvas.Stroke.Color := TAlphaColors.Aquamarine;
Bmp.Canvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
Bmp.Canvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(Bmp);
但是没用。我尝试了一段时间没有运气的几个想法:
- 据我的同事说,使用 Map/Unmap 直接访问位图数据对于大位图非常慢。
- 使用
TImage
和 DisableInterpolation=true
甚至 GlobalUseGPUCanvas=False
都不起作用。
- 使用
TPaintBox
组件不符合我们的需求。
- 解决方案是使用
Canvas.Quality=HighPerformance
,但它是只读的 属性。我尝试以不同的方式更改位图 Canvas.Quality
但它不起作用。
那么如何在Firemonkey中简单地画一条完全没有抗锯齿效果的线呢?
PS:我正在使用 Delphi 10.2.3(东京)
FireMonkey 在像素之间的网格上绘制线条,而不是在像素上绘制线条。所以你必须向每个坐标添加 0.5 才能在像素上绘制:
Bmp.Canvas.DrawLine(PointF(5.5, 5.5), PointF(100.5, 100.5), 1);
这不会禁用抗锯齿,但会避免在其他情况下发生的过度抗锯齿。我不知道禁用抗锯齿的 FireMonkey 函数。您必须调用本机 OS 函数,例如 Mac 上的 CGContextSetAllowsAntialiasing
OS,但一旦您弄清楚如何在像素上绘画,通常就不再需要它了。
最后我找到了一种方法来做到这一点。太简单了,我想知道溶液中是否有隐藏的毒药(笑)。 TCanvasManager
允许从给定位图创建高性能 Canvas。根据我的测试,它没有抗锯齿。这里的代码:
var
Bmp: TBitmap;
TmpCanvas: TCanvas;
begin
Bmp := TBitmap.Create(2000, 2000);
TmpCanvas := TCanvasManager.CreateFromBitmap(Bmp, TCanvasQuality.HighPerformance);
if (TmpCanvas.BeginScene) then
begin
TmpCanvas.Stroke.Color := TAlphaColors.Aquamarine;
TmpCanvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
TmpCanvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(TmpCanvas);
FreeAndNil(Bmp);
我还发现在 Canvas (Canvas.FillText
) 上写入文本的方法不起作用。
我希望这能帮助许多其他遇到同样问题的人。
我正在尝试制作一种位图编辑器,所以我只想在位图上画一条线,在 Firemonkey 中没有抗锯齿效果。像这样:
var
Bmp: TBitmap;
Bmp := TBitmap.Create(2000, 2000);
if (Bmp.Canvas.BeginScene) then
begin
Bmp.Canvas.Stroke.Color := TAlphaColors.Aquamarine;
Bmp.Canvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
Bmp.Canvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(Bmp);
但是没用。我尝试了一段时间没有运气的几个想法:
- 据我的同事说,使用 Map/Unmap 直接访问位图数据对于大位图非常慢。
- 使用
TImage
和DisableInterpolation=true
甚至GlobalUseGPUCanvas=False
都不起作用。 - 使用
TPaintBox
组件不符合我们的需求。 - 解决方案是使用
Canvas.Quality=HighPerformance
,但它是只读的 属性。我尝试以不同的方式更改位图Canvas.Quality
但它不起作用。
那么如何在Firemonkey中简单地画一条完全没有抗锯齿效果的线呢?
PS:我正在使用 Delphi 10.2.3(东京)
FireMonkey 在像素之间的网格上绘制线条,而不是在像素上绘制线条。所以你必须向每个坐标添加 0.5 才能在像素上绘制:
Bmp.Canvas.DrawLine(PointF(5.5, 5.5), PointF(100.5, 100.5), 1);
这不会禁用抗锯齿,但会避免在其他情况下发生的过度抗锯齿。我不知道禁用抗锯齿的 FireMonkey 函数。您必须调用本机 OS 函数,例如 Mac 上的 CGContextSetAllowsAntialiasing
OS,但一旦您弄清楚如何在像素上绘画,通常就不再需要它了。
最后我找到了一种方法来做到这一点。太简单了,我想知道溶液中是否有隐藏的毒药(笑)。 TCanvasManager
允许从给定位图创建高性能 Canvas。根据我的测试,它没有抗锯齿。这里的代码:
var
Bmp: TBitmap;
TmpCanvas: TCanvas;
begin
Bmp := TBitmap.Create(2000, 2000);
TmpCanvas := TCanvasManager.CreateFromBitmap(Bmp, TCanvasQuality.HighPerformance);
if (TmpCanvas.BeginScene) then
begin
TmpCanvas.Stroke.Color := TAlphaColors.Aquamarine;
TmpCanvas.DrawLine(PointF(5, 5), PointF(100, 100), 1);
TmpCanvas.EndScene;
Bmp.SaveToFile('c:\temp\result.bmp');
end;
FreeAndNil(TmpCanvas);
FreeAndNil(Bmp);
我还发现在 Canvas (Canvas.FillText
) 上写入文本的方法不起作用。
我希望这能帮助许多其他遇到同样问题的人。