如何在delphi firemonkey和android上使用抗锯齿 [英] How to work with anti-alias on delphi firemonkey and android

查看:119
本文介绍了如何在delphi firemonkey和android上使用抗锯齿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用firemonkey开发delphi xe7,并在android上进行测试。

I work on delphi xe7 with firemonkey and testing on android.

当我在正常分辨率为1(scene.scale = 1)的设备上工作时则TRoundRect,TPie等组件会产生丑陋的结果,因为它们没有抗锯齿(或者抗锯齿在人眼中看不到)。如果我在高清设备上工作(例如scene.scale = 2),那么这并不是一个大问题,因为高清可以弥补这一问题。

When i work on a device that have a normal resolution of 1 (scene.scale=1) then component like TRoundRect, TPie, etc produce ugly result because they are not anti-aliased (or the anti-alias is not visible by humain eyes). if i work on high definition device (scene.scale=2 for exemple), then it's not really a big problem because high definition compensate the problem.

那么第一个问题是,它们是否有任何办法可以使这些零件产生抗锯齿图形?
还要如何在画布上直接绘制抗锯齿的Disque(带有图像)?

So first question, is their any way to make theses component produce anti-alias graphic ? also how to draw directly on the canvas an anti-aliased disque (with an image in it) ?

现在,当我在位图和画布上工作时,我注意到FillText会产生抗锯齿效果。在某种程度上,这对我以前想要的(用于弥补)是有好处的,但对于文本来说却有点麻烦,因为这会使它们模糊。
,当我先执行Mybitmap.canvas.FillText =>产生一些抗锯齿,然后再执行MyPaintBox.canvas.DrawBitmap(MyBitmap)时,情况更糟,它将再次添加更多的抗锯齿!文本最后会变得很模糊:(对于我来说,
在进行canvas.drawBitmap而在srcRec和destRect中没有任何失真的情况下,并没有将确切的像素从位图复制到画布:(

Now when i work on bitmap and on canvas, i notice that the FillText produce anti-aliasing result. this is in someway good for what i want previously (for disque) but a little disaster for text because it's make them "blur". it's even worse when i do first Mybitmap.canvas.FillText => produce a little of antialias and then later i do MyPaintBox.canvas.DrawBitmap(MyBitmap) it's will add AGAIN more anti-alias ! the text will be very blur at the end :( it's sound crazy for me that doing canvas.drawBitmap without any distorsion in the srcRec and destRect not copy the exact pixel from bitmap to the canvas :(

所以这是他们的一种方法:

so it's their a way to :

调用 canvas.FillText
调用c anvas.DrawBitmap 完全没有任何抗锯齿!从位图到像素完美复制画布

Call canvas.FillText without any anti-alias or to configure the level of anti-alias. Call canvas.DrawBitmap without any anti-alias at all ! pixel perfect copy from bitmap to the canvas

在此先感谢您的帮助!

我今天发现了一些解决方案(以及它们的问题):

some solutions i found todays (and theirs problems) :

我找到了一种方法,可以使用抗锯齿功能制作所有可视控件(舍弃式等):设置Tform。质量到高品质!

I found a way how to make all the visual controls (troundrect, etc) with anti-aliasing : set Tform.quality to highQuality !

但是现在我正面临另一个我无法理解的非常强烈的问题:(
可能是delphi中的一个错误,因此如果有人可以看一下我将非常感谢他...

But now i m facing another very strong problem that i can not understand :( maybe a bug in delphi so if someone can look at it i will be very thanks to him ...

当您需要表格用画布时它是通过

when you need a canvas for the form it's created via

构造函数TCanvasGpu.CreateFromWindow(... AQuality:TCanvasQuality)

constructor TCanvasGpu.CreateFromWindow(...AQuality: TCanvasQuality)

取自MyForm.quality

and here the quality is taken from the MyForm.quality

现在问题出在TBITMAP :(与以前一样,当我们需要画布来通过它创建位图时,

now the problem is with TBITMAP :( same as previous when we need the canvas for the bitmap it's created via

构造函数TCanvasGpu.CreateFromBitmap(.... AQuality:TCanvasQuality = TCanvasQuality.SystemDefault)

constructor TCanvasGpu.CreateFromBitmap(....AQuality: TCanvasQuality=TCanvasQuality.SystemDefault)

但是这里的问题是根本不存在属性在位图中设置画布的质量:(

but here the problem their is NO PROPERTY at all in the bitmap to setup the quality of the canvas :(

所以我尝试此解决方案:

so i try this solution :

        aBitmap := Tbitmap.Create(w,h);
        try

          aCanvas := TCanvasManager.CreateFromBitmap(ABitmap, TCanvasQuality.HighQuality);
          Try

            aCanvas.BeginScene;
            try
              aCanvas.Fill.Kind := TbrushKind.solid;
              acanvas.Fill.Color := $ff000000;
              aCanvas.FillRect(TRectF.Create(0, 0, w, h), w / 2,  h / 2, ALLcorners, 1);

            finally
              aCanvas.EndScene;
            end;

          Finally
            aCanvas.Free;
          End;
          ....

我当时想我现在在我的位图上会保持不变我直接在表格的画布上绘制时所具有的抗锯齿效果?绝对不会,没有任何变化,并且我在没有任何抗锯齿的情况下仍然很难看:(

and i was thinking i will have now on my bitmap the same antialiasing effect of what i have when i draw directly on the canvas of the form ? absolutely not, nothing change and i still have ugly round without any anti-aliasing :(

我错过了什么?

编辑:

我现在发现去除抗锯齿的唯一选择是使位图增大2倍并将其减少2倍!crazy :(但是减少算法除去了别名...但是所有这些的代价是速度变慢,特别是当我们知道所有图形功能必须在主窗口中完成时线程:(

The only option i found for now to remove the antialias is to make the bitmap 2x more bigger and reduce it after by 2x! crazy :( but the algorithme of reduction remove the aliased ... but the cost of all of this is that the speed become slow, especially when we know that all the graphic function must be done in the main thread :(


  • 现在我想多了一点,我对自己说,拥有不支持多图形库的图形库是很疯狂的线程!我不敢相信这是openGL的要求,现在我越来越认为这是delphi中的错误或错误概念:(

  • Now more i think more i say to myself that it's crazy to have a graphic library that not support multi-thread ! i can not believe that it's a requirement of openGL and i think now more and more that it's a bug or bad conception in delphi :(

上一点,即使openGL确实要求所有图形例程必须在主线程中完成(但我真的很怀疑),我也不明白为什么delphi不提供andro功能id另一个支持多线程的TcanvasClass(TcanvasGPU除外)!更疯狂的是,当您在Tbitmap上使用TCanvasGPU时,在任何情况下(如您在我之前的文章中所见),结果都将与在可视组件上使用TCanvasGPU的结果有所不同!

Speaking about the previous point, even if openGL really required that all graphic routines must be done in the main thread (but really i doubt), i don't understand why delphi not offer on android another TcanvasClass (other than TcanvasGPU) that support multithread ! more crazy is that when you work with TCanvasGPU on Tbitmap, the result will be in any case (as you can see in my previous post) different from what you will have working with TCanvasGPU on the visual component !

现在我正在寻找直接在像素网格上工作的函数(旧式),这使我有可能在多线程中工作。但不幸的是,它们与firemonley / android不太兼容:(

now i m looking for function to work directly on pixels grids (old school), that will make me possible to work in multi-thread. but unfortunately their is not to much compatible with firemonley/android :(

来完成此功能,这是我用来绘制位图的功能。在主线程中被调用,这会减慢我的应用程序的速度(尤其是滚动)……因此,如果您有任何想法可以使此程序更快或更快速,请采取以下措施:)

to finish this is the function i use to draw my bitmap. but as this function must be call in the main thread, it's slow down my application (especially the scroll) ... so if you have any idea to make this more fast or multithread i take :)

function DrawAdvertBitmap: Tbitmap;
var aBitmapAliased: Tbitmap;
begin

  aBitmapAliased := Tbitmap.Create(trunc(FWidth * fScreenScale) * 2, trunc(FHeight * fScreenScale) * 2);

  try

    aBitmapAliased.Canvas.BeginScene;
    try

      aBitmapAliased.canvas.Clear(0);
      aBitmapAliased.canvas.Fill.Color := $ff000000;
      aBitmapAliased.Canvas.Fill.Kind := TbrushKind.Solid;
      aBitmapAliased.Canvas.FillRect(...);

      aBitmapAliased.Canvas.Fill.Color := $ff333844;
      aBitmapAliased.Canvas.Font.Family := 'Roboto-Bold';
      aBitmapAliased.Canvas.Font.Size := 12 * fScreenScale * 2;
      aBitmapAliased.Canvas.Font.Style := [TFontStyle.fsBold];
      aBitmapAliased.Canvas.FillText(...);

    finally
      aBitmapAliased.Canvas.EndScene;
    end;

    //reduce by 2 to make antialiased
    result := Tbitmap.Create(trunc(FWidth * fScreenScale), trunc(FHeight * fScreenScale));

    try

      result.Canvas.BeginScene;
      try

        result.Canvas.Clear(0);
        result.Canvas.DrawBitmap(aBitmapAliased,...);

      finally
        result.Canvas.EndScene;
      end;

    except
      result.Free;
      raise;
    end;

    result.BitmapScale := fScreenScale;

  finally
    aBitmapAliased.free;
  end;

end; 


推荐答案

如果您在某些控件上看到奇怪的抗锯齿,我建议您检查一下控件是否没有小数位和大小值,请确保在位置上使用trunc / round或GPU画布使用一些低质量的

If you are seeing weird anti-aliasing on some controls, I would recommend that you check that the controls do not have fractional position and size values, make sure to use trunc/round on the position or the GPU canvas uses some low-quality interpolation effect on top of any anti-aliasing.

如果您打算按像素进行手动调整,则建议您使用优化的颜色转换代码(scanline< > TAlphaColor)作为内置代码是专为清除代码而不是性能而设计的:
https:// github.com/bLightZP/OptimizedDelphiFMXScanline

If you plan to do per-pixel manual adjustments, I recommend that you use optimized color-conversion code (scanline <> TAlphaColor) as the built-in code is designed for clear code and not performance: https://github.com/bLightZP/OptimizedDelphiFMXScanline

对于绘制带有图片的抗锯齿圆圈,我发现最简单的方法是生成抗锯齿不透明度贴图,并将其应用于TImage的TBitmap。您可以在此处找到用于生成消除锯齿的不透明度贴图的代码:
https://github.com/ bLightZP / AntiAliasedCircle

As for drawing anti-aliased circles with pictures in them, I found the easiest way is to generate an anti-aliased opacity map and apply it to a TImage's TBitmap. You can find code for generating an anti-aliased opacity map here: https://github.com/bLightZP/AntiAliasedCircle

这篇关于如何在delphi firemonkey和android上使用抗锯齿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆