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



我有一个简单的位图,我在画布上绘制,然后使用矩阵旋转。

我遇到的问题是,使用硬件加速时,边缘在旋转时不会抗锯齿(这在关闭硬件加速的情况下完美运行(。当然,像"setDrawFilter"这样的东西是无用的,因为它们在打开硬件加速时会被忽略!

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

我错过了什么还是只是硬件渲染方法的限制?还有其他选择吗?

无论如何,

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

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

拥有"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 色块相结合以获得透明边框,但我们不能组成 2 个位图着色器......所以,我又来了。如何获得这个面具着色器!该死的墙;)

修复了在我的情况下有效的问题:

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

详:

我的文本视图使用 9 个色块作为背景,因此我无法在不影响 9 个色块像素的情况下添加透明的 1px 边框。因此,相反,我能够通过禁用给定视图及其父视图的硬件加速来使其工作:

我在视图膨胀之后称之为。特别是在我的情况下onCreateViewHolder(确切地说是在视图持有者构造函数中(。这修复了我的旋转文本视图,它使用NinePatchDrawable背景,类似于以下内容:

<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"/>

相关内容

最新更新