位图未绘制抗锯齿 [英] Bitmap not drawn anti-aliased

查看:31
本文介绍了位图未绘制抗锯齿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的 View,它总是在某个旋转位置绘制一个 Bitmap.我覆盖了 onDraw 方法,旋转 Canvas 并使用抗锯齿的 Paint 绘制位图.

I have a custom View that always draws a Bitmap at a certain rotation. I overwrite the onDraw method, rotate the Canvas and draw the bitmap with an anti-aliased Paint.

public RotatedImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    someBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.placeholder);
}

@Override
protected void onDraw(Canvas canvas) {

    // Save and rotate canvas
    canvas.save();
    canvas.rotate(3F, getWidth() / 2, getHeight());

    // Draw the icon
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    canvas.drawBitmap(someBitmap, 0, 0, p);
    canvas.drawRoundRect(new RectF(75, 50, 225, 200), 10, 10, p);

    // All done; restore canvas
    canvas.restore();
}

但是,我总是在位图上看到锯齿状边缘.请注意,圆角矩形获得了很好的抗锯齿边缘.此外,当我应用 p.setFilterBitmap(true); 时,这可以正确工作(位图表面被过滤/平滑).我错过了什么吗?

However, I always get jagged edges on the Bitmap. Note that the roudned rectangle gets nicely anti-aliased edges. Also, when I apply p.setFilterBitmap(true); this works (the bitmap surface gets filtered/smoothed) correctly. Am I missing something?

这是一个最小的 Android 项目,带有一个单独的屏幕示例,显示了从资源加载的绘制非抗锯齿位图的视图:https://bitbucket.org/erickok/antialiastest

Here's a minimal Android project with isolated example of one screen that shows the View that draws the non-anti-aliased Bitmap, loaded from a resource: https://bitbucket.org/erickok/antialiastest

更新:我还尝试了以下内容:

    Paint p = new Paint();
    p.setAntiAlias(true);
    p.setFilterBitmap(true);
    p.setDither(true);
    canvas.drawBitmap(someBitmap, 0, 0, p);

但这无济于事,因为 setFilterBitmap 过滤表面;它不会消除边缘锯齿.此外,setAntiAlias 与在 Paint 构造函数中直接设置标志的作用相同.如果有疑问,请尝试我的最小测试项目.非常感谢您的帮助!

But this doesn't help as setFilterBitmap filters the surface; it does not anti-alias the edges. Also, setAntiAlias does the same as directly setting the flag in the Paint constructor. If in doubt, please try my minimal test project. Thanks so much for any help!

推荐答案

我找到了为什么我没有得到任何抗锯齿:硬件加速.在我(纯属偶然)在我的 Nexus One 上测试后,它突然起作用了,而我的 Nexus 7 却没有.事实证明,当使用硬件加速绘制 Canvas 时,ANTI_ALIAS_FLAG 什么也不做.有了这种洞察力,我发现 Romain Guy 在 StackOverflow 上的回答 回答了我的问题.

I have found why I did not get any anti-aliasing: hardware acceleration. After I (by pure accident) tested on my Nexus One it suddenly worked, while my Nexus 7 didn't. Turns out that the ANTI_ALIAS_FLAG does nothing when the Canvas is drawn using the hardware acceleration. With that insight I found Romain Guy's answer on StackOverflow which answers my question.

解决方案似乎是:为每个位图添加透明边框(手动或动态)或使用着色器做一些事情".两者都对我没有吸引力.相反,我 禁用硬件加速 在我的自定义视图上使用 setLayerType 方法.请注意,这从 API 级别 11 开始就可用,但(并非偶然)在任何情况下您都不必处理硬件加速.所以我在视图构造函数中添加了:

Solutions seem to be: adding a transparent border to every bitmap (manually or on the fly) or 'do something with shaders'. Neither are very appealing to me. Instead I disabled hardware acceleration on my custom view using the setLayerType method. Note that this is available since API level 11, but (not by accident) you won't have to deal with hardware acceleration before any way. So I have added, in the view constructor:

    if (android.os.Build.VERSION.SDK_INT >= 11) {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

我已经为感兴趣的人更新了上面引用的 BitBucket 上的开源项目.

I've updated the above referenced open-source project on BitBucket for those interested.

这篇关于位图未绘制抗锯齿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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