具有硬件加速功能的Canvas抗锯齿功能(Android API 11及更高版本)

时间:2012-03-16 00:33:54

标签: android android-3.0-honeycomb

我有一个简单的位图,我在画布和画布中绘制我用矩阵旋转。

我遇到的问题是使用硬件加速时,边缘在旋转时不会消除锯齿(这与硬件加速关闭时完美配合)。 当然,像“setDrawFilter”这样的东西是没用的,因为在打开硬件加速时它们会被忽略!

canvas.setDrawFilter(new PaintFlagsDrawFilter(1, Paint.ANTI_ALIAS_FLAG));

我是否遗漏了某些内容或仅仅是硬件渲染方法的限制?还有其他选择吗?

3 个答案:

答案 0 :(得分:8)

无论如何,在油漆上设置抗锯齿标志都无济于事。要在旋转位图时在位图上获得抗锯齿边框,您应该在它们周围添加1px透明边框。

答案 1 :(得分:1)

添加这个1px透明边框并不像我想象的那么容易。在运行时添加它真的很乱。我的应用程序加载了很多位图,并添加此边框我需要分配更多的位图来重绘它们。这真的破坏了堆,但由于我小心翼翼地避免任何内存泄漏,它按预期工作。真正让我感到害怕的是它引入的“滞后”。我追踪了流失到GC的流动性。最后一个似乎是在他回收再生位图时放慢了UI线程的速度。 使用缓存也不是解决方案。这是实现性能的最佳方式,但存储500x500 PNG(alpha强制)是不成比例的。 所以,我在这里,撞墙。我还没有尝试过“绘制时间”的方式,但我的猜测是绘制到屏幕外的位图缓冲区,我认为这不会是HW acc。 (如果我错了,请纠正我)对我的事业没有帮助。

拥有“AA着色器”的想法真的很诱人,我在这里看到了几个优点。它受到硬件加速的良好支持,当然会成为内存的奇迹(不再是野蛮的位图分配),并且可以完全独立于位图缩放。 我做了一个快速测试,这是迄今为止最好的AA(在这里我的意思是质量)我设法得到...它很快......这个快速总结使用着色器做上边缘AA。

        BitmapShader bitmapShader = new BitmapShader(mBitmap,
                TileMode.CLAMP, TileMode.CLAMP);
        Matrix m = new Matrix(); 
        m.postTranslate(0, 1); 
        bitmapShader.setLocalMatrix(m); 

        final LinearGradient AAshader = new LinearGradient(0, 0, 0, 1, 0x00000000, 0xffffffff, TileMode.CLAMP);

        ComposeShader compositor = new ComposeShader(bitmapShader,
                AAshader, PorterDuff.Mode.DST_IN);

        mPaint.setShader(compositor);
        canvas.drawRect(this.getBounds(), mPaint);

现在最大的缺点!如何获得4边AA :) ???我们可以使用多步梯度来管理上/下边缘AA,但这仍然很脏。一个很好的方法是将源位图与某种9-patch组合以获得透明边框,但是我们不能编写2位mapShader ......所以,我再次在这里。如何获得这个面具着色器!该死的墙;)

答案 2 :(得分:-1)

修复了我的情况:

private void fixAntiAlias(View viewFromThe80s) {
    if (Build.VERSION.SDK_INT > 10) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
        viewFromThe80s.setLayerType(View.LAYER_TYPE_SOFTWARE, p);
        ((View) viewFromThe80s.getParent()).setLayerType(View.LAYER_TYPE_SOFTWARE, p);
    }
}

详细信息:

我的textview使用9补丁作为背景,所以我无法添加透明的1px边框而不会影响9补丁像素。因此,相反,我能够通过禁用给定视图及其父级的硬件加速来实现此功能:

在看到通货膨胀后,我正在呼吁这一点。特别是在我的情况下onCreateViewHolder(在视图构造函数中准确)。这修复了我使用NinePatchDrawable背景的旋转TextView,类似于以下内容:

<TextView
    android:id="@+id/text_new_feature"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:rotation="-30"
    android:background="@drawable/background_new_feature"/>