画布绘制缓存位图略有模糊或具有反锯齿效果。

3
在我的应用程序中,我编写了自己的SVG转换器,将原始SVG XML文件转换为一系列图形向量对象(Paint、Path等),然后应用于Canvas。SVG数据首先被转换为一种类似字节码格式的形式,连同路径列表等一起,这意味着初始XML解析只需要进行一次,之后每次重绘SVG图形都可以相对较快地完成。SVG转换在运行时完成的事实使我能够对各种图形元素执行一些程序操作。例如,我可以在Inkscape中绘制一个图形温度计,在运行时代码会操作仪表的刻度并移动指针。这就是为什么我“需要”使用矢量操作绘制静态背景图形和移动图形,而不是编译静态位图。无论如何,这是我正在做的一点背景信息;我将进入实际问题。
假设一个典型的仪表小部件由两个叠加的视图组成。背景视图包含静态图形(仪表的圆形面、数字图例、刻度线),这些图形是使用Paths绘制的。前景视图包含需要经常重新绘制的指针图形。每个小部件可能会使用RelativeLayout来包含这些子视图。
我意识到,每当调用前景指针视图的onDraw()时,后面的背景视图的onDraw也会被调用。因此,为了优化小部件的重绘时间,我尝试利用Canvas的绘图缓存来处理背景视图。我的做法确实有效,并且结果是重绘速度大幅提高,但问题在于我保存并稍后重新绘制到Canvas的缓存位图从未像使用Paths最初绘制的那样锐利。
我在背景视图的onDraw()方法中使用的基本代码是:
Bitmap bm = null;

onDraw(Canvas canvas){

    if(bm!=null){
        Paint bitmapPaint = new Paint();
        bitmapPaint.setAntiAlias(false);
        bitmapPaint.setFilterBitmap(false);
        bitmapPaint.setDither(false);
        canvas.drawBitmap(bm, 0, 0, bitmapPaint);

        return;             
    }


    ... Vector drawing to the Canvas using Path objects happens here,
        performed by the SVG converter object ... 


    setDrawingCacheEnabled(true);   
    setDrawingCacheQuality(DRAWING_CACHE_QUALITY_HIGH);
    bm = Bitmap.createBitmap(getDrawingCache());
}

为了尽可能提高位图的质量,我已经做了以下几件事情:
  1. 确保缓存绘制质量高。

  2. 在绘制位图时,使用一个关闭反锯齿、抖动等功能的Paint对象(bitmapPaint)。

  3. 知道任何对位图的缩放都会立即影响其质量,我(希望)确保不需要对位图进行缩放。我将视图大小设置为与原始SVG图像完全相同,这意味着我的SVG转换代码不会对画布进行缩放。scale()调用总是由SVG转换器执行,但在当前情况下,它的参数是canvas.scale(1,1)。如果我故意更改视图的宽度/高度与原始SVG图像不匹配,则Canvas缩放不再是1,1,那么位图的质量损失就非常明显。

所以我的主要问题是,我使用上面的代码来利用绘制缓存位图是否有任何问题?我有一种感觉,在屏幕上显示的位图尺寸与我绘制的原始图形完全相同,但我不知道位图上是否发生了某种密度/缩放。
此外(可能超出主要问题的范围),是否有其他技术可以避免在前景移动图形时重新绘制背景矢量图形?据我所知,使用位图缓存是目前我所知道的唯一方法。
提前感谢您的任何建议。
1个回答

3
我很高兴地说,问题现在已经解决了。我意识到在第一次传递给onDraw()的Canvas已经应用了一些缩放。这个缩放存在是导致位图质量下降的原因。但我不明白为什么Canvas应该已经有一些缩放。
我发了另一个问题来询问这个问题: 在onDraw()方法中,为什么提供的Canvas已经有了缩放? 那里接受的答案表明我可能没有指定android:minSdkVersion。确实,非常愚蠢的是我还没有指定。一旦我指定了minSdkVersion,缓存位图现在可以画得很漂亮了。令人惊讶的是,直到现在我才意识到我绘制的图像并不是手机的正确屏幕分辨率;由于缺乏minSdkVersion,它们都被缩放了。
功劳归于adamp!

感谢您发布您的解决方案! - RichieHindle
请参考以下链接,了解另一种方法:https://dev59.com/3GbWa4cB1Zd3GeqPVUw8 - Ron

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接