21

我有一个习惯View,总是Bitmap在某个旋转时绘制 a 。我覆盖该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();
}

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

照片上没有抗锯齿

这是一个最小的 Android 项目,其中一个屏幕的孤立示例显示了从资源加载的绘制非抗锯齿位图的视图: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构造函数中直接设置标志相同。如果有疑问,请尝试我的最小测试项目。非常感谢您的帮助!

4

5 回答 5

22

使用 setFilterBitmap(true)。

paint_object.setFilterBitmap(true);

它也对我有用..我从这个问题中得到了它

使用抗锯齿绘制旋转位图

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);
于 2013-01-19T06:55:09.000 回答
19

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

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

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

对于那些感兴趣的人,我已经在 BitBucket 上更新了上面引用的开源项目。

于 2013-01-22T12:59:12.907 回答
5

就我而言,我这样做了,但可能就像你一样:

Paint paint = new Paint();
paint.setAntiAlias(true);

你试一试。

祝你好运!

于 2013-01-17T12:06:53.563 回答
4

我测试了以前的建议,它们确实对我有用。也许问题出在您的位图中?也许在您的设备中?这是一个内联创建位图的代码。检查此示例是否适合您。

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();
    }
  }
}
于 2013-01-21T17:23:08.693 回答
2

我有同样的问题,并尝试了所有这些修复。最终奏效的是在 AndroidManifest.xml 文件中全局禁用硬件加速:

 <application
       android:hardwareAccelerated="false" 
  ...
 >

然后在我加载图像位图时禁用 inSampleSize,这样(我认为)图像将以足够高的质量加载以避免任何曲折,然后,对于我的实际 ImageView,使用上述建议:将图层类型设置为 View .LAYER_TYPE_SOFTWARE,带有过滤器位图设置为 true(如上)和抗锯齿的绘制对象。

于 2014-05-01T06:18:37.080 回答