绘图画布缓存位图是有点模糊或者具有抗混叠 [英] Canvas drawing cache bitmap is slightly blurred or has anti-alias

查看:402
本文介绍了绘图画布缓存位图是有点模糊或者具有抗混叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序已经推出自己的SVG转换器将原始SVG XML文件导入图形矢量对象(油漆,路径等),然后将其应用到画布的序列。 SVG的数据首先被转换成一种字节code格式与路径的列表等。这意味着最初的XML解析只进行一次,再后每重新绘制SVG图形可以相当快的发生。该SVG转换是在运行时,这一事实使我对各种图形元素进行一些程序操作。例如,我可以得出一个图形化的温度测量仪在Inkscape中,并在运行时code操纵计的规模,围绕移动指针。这就是为什么我需要'画静态背景图形,以及使用向量运算移动显卡,而不是编译静态位图。无论如何,这是背景信息,我在做什么一点点;我会移动到实际问题。

In my application I have rolled my own SVG converter that translates a raw SVG XML file into a sequence of graphical vector objects (Paint, Path, etc.) which are then applied to Canvas. The SVG data is first converted into a kind of bytecode format together with Lists of Paths, etc. which means that initial XML parsing is only done once, and then thereafter each redraw of the SVG graphics can happen reasonably fast. The fact that SVG conversion is done at run-time enables me to perform some program manipulations on various graphical elements. For example, I can draw a graphical temperature gauge in Inkscape and at runtime the code manipulates the scale of the gauge and moves the pointer around. This is why I 'need' to draw both static background graphics as well as moving graphics using vector operations, as opposed to compiling static bitmaps. Anyway, this is a little bit of background information for what I'm doing; I'll move onto the actual question.

比方说,一个典型的计部件是由两个叠加的意见。背景视图包含静态图形(压力表的圆形面,数字传说,刻度线),其采用的路径绘制。前景视图包含图形以需要频繁地重画的指针。每个窗口小部件应可能使用一个RelativeLayout的包含这些孩子的意见。

Let's say a typical gauge widget is composed of two overlayed Views. The background View contains static graphics (the circular face of the gauge, numeric legends, tick marks) that were drawn using Paths. The foreground View contains the graphics for the pointer that needs to be redrawn frequently. Each widget shall probably use a RelativeLayout to contain these children views.

我意识到,只要的OnDraw()被调用的前景指针视图,那么OnDraw中被调用的backgound查看,坐在后面。因此,优化部件重绘的时候,我已尝试使用画布绘制缓存为背景查看。我做了什么做的工作,结果在一个伟大的重绘速度加息,但问题是,高速缓存的位图,我保存,然后重新绘制到画布后从来就作为锋利的使用路径什么最初绘制。

I realise that whenever the onDraw() is called for the foreground pointer View, then the onDraw is to be called for the backgound View that sits behind it. Therefore, to optimise the widget redraw time, I've attempted to make use of the Canvas' drawing cache for the background View. What I have done does work and results in a great redraw speed hike, but the problem is that the cache bitmap that I save and then redraw to the Canvas later is never quite as razor-sharp as what was originally drawn using the Paths.

基本code,我在我的OnDraw()方法为背景查看使用的是:

The basic code I've used in my onDraw() method for the background View is:

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());
}

要设法得到位图的质量有高有可能,我也做了以下事情:

To try to get the quality of the bitmap has high as possible, I have done the following things:

  1. 确保缓存绘图质量高。

  1. Ensured that the cache drawing quality is high.

与抗混叠,抖动等使用一个画图对象(bitmapPaint)绘制位图时禁用。

Used a Paint object (bitmapPaint) with anti-alias, dither, etc. disabled when drawing the bitmap.

知道了位图的任何缩放将立即影响其质量,我(希望)确保没有缩放的位图的应该需要被执行。我给自己定的视图的大小是完全原始SVG图像,这意味着我的SVG转换器code适用不结垢到画布。的水垢()调用总是由SVG转换器进行的,但在present情况它是由与参数canvas.scale(1,1)。如果我要故意改变视图的宽度/高度不匹配原始SVG图像,画布缩放不再是1,1和质量的位图,然后进一步的损失是非常明显的。

Knowing that any scaling of the bitmap would immediately affect its quality, I've (hopefully) ensured that no scaling of the bitmap should need to be performed. I've set the size of the View to be exactly that of the original SVG image, which means that my SVG converter code applies no scaling to the Canvas. A scale() call is always performed by the SVG converter, but in the present situation it's made with the arguments canvas.scale( 1, 1). If I were to intentionally change the width / height of the View to mismatch that of the original SVG image, Canvas scaling is no longer 1,1 and then further loss of quality to the bitmap is very much apparent.

所以我的主要问题是,有什么不对的code我上面用来利用绘图缓存位图?我有一种感觉,有某种密度/规模发生在我是不知道的位图,即使它出现在屏幕尺寸完全相同的原始图形我画的。

So my main question is, is there anything wrong with the code I've used above to make use of the drawing cache bitmap? I've got a feeling that there's some kind of density / scale happening to the bitmap that I'm unaware of, even though it's appearing on the screen exactly the same size as the original graphics I had drawn.

另外(可能是走出去的主要问题的范围),还有没有其他的方法,我可以使用,以避免背景矢量图形重绘时,有前景的移动图形?据我所知,使用位图缓存是我所知的唯一办法为止。

Furthermore (possibly going out of the scope of the main question) is there any other technique I could employ to avoid redraw of background vector graphics when there are foreground moving graphics? As far as I can tell, using the bitmap cache is the only way to my knowledge so far.

在此先感谢;任何意见将是非常美联社preciated。

Thanks in advance; any advice would be much appreciated.

崔佛

推荐答案

我很高兴地说,这个问题现在已经得到解决。我意识到,画布被传递到的OnDraw()摆在首位已经有一定比例使用。的事实,这是缩放有什么降解位图的质量。但我不明白为什么画布应该已经有一定的比例。

I'm pleased to say that the problem is now resolved. I realised that the Canvas being passed to onDraw() in the first place already had some scaling applied. The fact that this scaling is there is what's degrading the quality of the bitmap. But I could not understand why the Canvas should already have some scaling.

我张贴另一个问题想请教一下这个在这里:<一href="http://stackoverflow.com/questions/6286483/in-the-ondraw-method-why-does-the-supplied-canvas-already-have-scale/6286899#6286899">In的的OnDraw()方法时,为什么提供的帆布已经有规模有多大?。接受的答案,建议我可能没有指定的机器人:的minSdkVersion。事实上,相当愚蠢的我却没有。有一次,我指定的minSdkVersion,缓存位图现在绘制精美。令人惊讶的我没有意识到到现在为止,我在画的图像进行的没有应用于手机的合适的屏幕分辨率;他们都被缩放因缺乏的minSdkVersion的。

I posted another question to ask about this here: In the onDraw() method, why does the supplied Canvas already have scale?. The accepted answer there suggests that I may not have specified android:minSdkVersion. Indeed, quite stupidly I hadn't. Once I specified the minSdkVersion, the cache bitmap now draws beautifully. Amazingly I had not realised until now that the images I was drawing were not to the phone's proper screen resolution; they were all being scaled due to lack of minSdkVersion.

信贷由于adamp!

这篇关于绘图画布缓存位图是有点模糊或者具有抗混叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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