我有一个自定义View
,在某个轮播时总是会Bitmap
。我覆盖onDraw
方法,旋转Canvas
并使用消除锯齿的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();
}
但是,我总是在Bitmap上出现锯齿状边缘。请注意,roudned矩形可以很好地消除锯齿边缘。此外,当我应用p.setFilterBitmap(true);
时,这可以正常工作(位图表面被过滤/平滑)。我错过了什么吗?
这是一个最小的Android项目,其中一个屏幕的隔离示例显示了绘制从资源加载的非消除锯齿的Bitmap的视图: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
构造函数中直接设置标志的作用相同。如有疑问,请尝试我的最小测试项目。非常感谢您的帮助!
答案 0 :(得分:20)
我发现为什么我没有得到任何抗锯齿:硬件加速。在我(通过纯粹的意外)在我的Nexus One上测试后它突然起作用,而我的Nexus 7没有。事实证明,ANTI_ALIAS_FLAG
在使用硬件加速绘制Canvas
时不执行任何操作。凭借这种洞察力,我发现Romain Guy's answer on StackOverflow回答了我的问题。
解决方案似乎是:为每个位图添加透明边框(手动或动态)或“使用着色器执行某些操作”。对我来说都没有吸引力。而是使用setLayerType
方法在我的自定义视图上disabled hardware acceleration。请注意,这可以从API级别11开始,但(不是偶然)您不必在任何方式之前处理硬件加速。所以我在视图构造函数中添加了:
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
我已经为BitBucket更新了上面提到的开源项目给那些感兴趣的人。
答案 1 :(得分:19)
使用setFilterBitmap(true)。
paint_object.setFilterBitmap(true);
它对我也有用.. 我从这个问题中得到了它
Drawing rotated bitmap with anti alias
将 AntiAlias 标志和 FilterBitmap 标志设置为true,它们一起使位图的边缘平滑,我已经在Samsung Galaxy Ace,android 2.2上测试了它...
我的测试代码是
Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
canvas.drawBitmap(someBitmap, new Matrix(), p);
答案 2 :(得分:6)
就我而言,我这样做了,但可能就像你做的那样:
Paint paint = new Paint();
paint.setAntiAlias(true);
试试吧。
祝你好运!答案 3 :(得分:3)
我测试了以前的建议,他们确实为我工作。也许问题出在你的位图中?也许在你的设备?这是一个内联创建位图的代码。检查此示例是否适合您。
public class BitmapRotateActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
class MyView extends View {
Bitmap bitmap;
public MyView(Context context) {
super(context);
bitmap = Bitmap.createBitmap(160, 160, Bitmap.Config.RGB_565);
Paint p = new Paint();
p.setColor(Color.RED);
p.setStyle(Paint.Style.FILL);
Canvas c = new Canvas(bitmap);
c.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), p);
}
@Override
protected void onDraw(Canvas canvas) {
Paint pbg = new Paint();
pbg.setStyle(Paint.Style.FILL);
pbg.setColor(0xffe0e0ff);
canvas.drawRect(0, 0, getWidth(), getHeight(), pbg);
Paint p = new Paint();
p.setAntiAlias(true);
p.setFilterBitmap(true);
canvas.save();
canvas.rotate(3F, getWidth() / 2, getHeight() / 2);
canvas.drawBitmap(bitmap, 30, 30, p);
canvas.restore();
}
}
}
答案 4 :(得分:3)
我遇到了同样的问题,并尝试了所有这些修复程序。最终有效的是全局禁用AndroidManifest.xml文件中的硬件加速:
<application
android:hardwareAccelerated="false"
...
>
然后在我加载我的图像位图时禁用inSampleSize,这样(我认为)图像将以足够高的质量加载以避免任何曲折,然后,对于我的实际ImageView,使用上述建议:设置图层键入View.LAYER_TYPE_SOFTWARE,使用绘制对象,将滤镜位图设置为true(如上所述)并消除锯齿。