gpt4 book ai didi

android - Canvas 绘图缓存位图略微模糊或具有抗锯齿

转载 作者:太空狗 更新时间:2023-10-29 12:56:27 27 4
gpt4 key购买 nike

在我的应用程序中,我推出了自己的 SVG 转换器,将原始 SVG XML 文件转换为一系列图形矢量对象(Paint、Path 等),然后将其应用于 Canvas。 SVG 数据首先与路径列表等一起转换为一种字节码格式,这意味着初始 XML 解析仅进行一次,然后 SVG 图形的每次重绘都可以相当快地发生。 SVG 转换是在运行时完成的这一事实使我能够对各种图形元素执行一些程序操作。例如,我可以在 Inkscape 中绘制一个图形温度计,在运行时代码会操纵仪表的刻度并四处移动指针。这就是为什么我“需要”使用矢量操作绘制静态背景图形和移动图形,而不是编译静态位图。无论如何,这是我正在做的事情的一些背景信息;我将继续讨论实际问题。

假设一个典型的仪表小部件由两个重叠的 View 组成。背景 View 包含使用路径绘制的静态图形(仪表的圆形面、数字图例、刻度线)。前景 View 包含需要经常重绘的指针的图形。每个小部件可能应该使用 RelativeLayout 来包含这些 subview 。

我意识到,每当为前景指针 View 调用 onDraw() 时,就会为位于它后面的背景 View 调用 onDraw。因此,为了优化小部件重绘时间,我尝试将 Canvas 的绘图缓存用于背景 View 。我所做的工作确实有效并导致重绘速度大幅提升,但问题是我保存然后重绘到 Canvas 的缓存位图从来没有像最初使用路径绘制的那样锐利。

我在背景 View 的 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. 我知道位图的任何缩放都会立即影响其质量,因此我(希望)确保无需执行位图缩放。我已将 View 的大小设置为与原始 SVG 图像完全相同,这意味着我的 SVG 转换器代码不对 Canvas 应用缩放。 scale() 调用始终由 SVG 转换器执行,但在当前情况下,它是使用参数 canvas.scale(1, 1) 进行的。如果我故意将 View 的宽度/高度更改为与原始 SVG 图像的宽度/高度不匹配,Canvas 缩放比例将不再是 1,1,然后位图的质量进一步下降将非常明显。

所以我的主要问题是,我上面使用绘图缓存位图的代码有什么问题吗?我有一种感觉,位图上发生了某种我没有意识到的密度/比例,即使它出现在屏幕上与我绘制的原始图形的大小完全相同。

此外(可能超出主要问题的范围)有没有其他技术可以用来避免在有前景移动图形时重绘背景矢量图形?据我所知,使用位图缓存是目前我所知的唯一方法。

提前致谢;任何建议将不胜感激。

崔维

最佳答案

我很高兴地说,这个问题现在已经解决了。我意识到首先传递给 onDraw() 的 Canvas 已经应用了一些缩放。这种缩放存在的事实会降低位图的质量。但我不明白为什么 Canvas 应该已经有一些缩放。

我在这里发布了另一个问题:In the onDraw() method, why does the supplied Canvas already have scale? .那里接受的答案表明我可能没有指定 android:minSdkVersion。确实,很愚蠢我没有。一旦我指定了 minSdkVersion,缓存位图现在绘制得很漂亮。令人惊讶的是,直到现在我才意识到我正在绘制的图像手机的正确屏幕分辨率;由于缺少 minSdkVersion,它们都被缩放了。

归功于 adamp!

关于android - Canvas 绘图缓存位图略微模糊或具有抗锯齿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6278509/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com