首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用硬件加速的画布抗锯齿功能(Android API 11及更高版本)

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

Stack Overflow用户
提问于 2012-03-16 08:33:54
回答 3查看 4.3K关注 0票数 5

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

我遇到的问题是,使用硬件加速时,边缘在旋转时不会抗锯齿(这在硬件加速关闭的情况下工作得很好)。当然,像“setDrawFilter”这样的东西是没有用的,因为当硬件加速开启时,它们会被忽略!

代码语言:javascript
复制
canvas.setDrawFilter(new PaintFlagsDrawFilter(1, Paint.ANTI_ALIAS_FLAG));

我是否遗漏了什么,或者这只是硬件渲染方法的限制?还有别的选择吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-16 09:43:06

在绘图上设置抗锯齿标志无论如何都不会有什么帮助。要在旋转时在位图上获得抗锯齿边框,您应该在它们周围添加一个1px的透明边框。

票数 9
EN

Stack Overflow用户

发布于 2012-03-29 19:20:06

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

有一个“AA着色器”的想法真的很诱人,我在这里看到了几个优点。它得到了硬件加速的很好支持,当然这将是内存的奇迹(不再需要更多的原始位图分配),并且可以完全独立于位图缩放。我做了一个快速测试,这是迄今为止我得到的最好的AA (这里我指的是质量)和…它是快速的…此快速总结使用着色器执行上边AA。

代码语言:javascript
复制
        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位图border…所以,我又一次来到这里。如何获得此遮罩着色器!可恶的墙;)

票数 0
EN

Stack Overflow用户

发布于 2016-12-22 04:27:29

修复在我的案例中有效的方法:

代码语言:javascript
复制
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-patch作为背景,因此我无法在不影响9-patch像素的情况下添加透明的1px边框。因此,相反,我可以通过禁用给定视图及其父视图的硬件加速来使其正常工作:

在视图膨胀之后,我将其称为。在我的例子中,特别是在onCreateViewHolder中(确切地说,在viewholder构造函数中)。这修复了我使用NinePatchDrawable背景的旋转TextView,如下所示:

代码语言:javascript
复制
<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"/>
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9730249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档