将硬件加速的android画布保存为位图

时间:2014-09-26 06:13:40

标签: android canvas view bitmap hardware-acceleration

我目前正在直接绘制提供给我视图的onDraw方法的Canvas对象。这个画布是硬件加速的。特别是,我使用RadialGradient着色器和OVERLAY PorterDuff模式绘制多个圆圈。但是,当我尝试将相同的绘制过程应用于我手动创建的画布时,我得不到相同的结果。我相信这是因为为位图创建的canvas对象不是硬件加速的。

视图的代码如下所示:

public class MyView extends View {
  private Paint mPaint;
  private List<Shader> mShaders;

  public MyView(Context context) {
    super(context);

    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG|Paint.DITHER_FLAG);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));

    mShaders = new ArrayList<Shader>(); // assume x, y, r, and color vals are defined.
    mShaders.add(new RadialGradient(x1, y1, r1, c11, c12, Shader.TileMode.CLAMP));
    mShaders.add(new RadialGradient(x2, y2, r2, c21, c22, Shader.TileMode.CLAMP));
  }

  @Override
  protected void onDraw(Canvas canvas) {
    mPaint.setShader(mShaders.get(0));
    canvas.drawCircle(x1, y1, r1, mPaint);

    mPaint.setShader(mShaders.get(1));
    canvas.drawCircle(x2, y2, r2, mPaint);
  }
}

到目前为止,一切都很顺利。圆圈在硬件加速画布上按预期绘制。

但是,如果我这样做:

...
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
draw(canvas);

或其中的一些变体:

...
setDrawingCacheEnabled(true);
buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(getDrawingCache());
destroyDrawingCache();
setDrawingCacheEnabled(false);

或者如果我尝试使用相同的着色器和绘制标记绘制,例如,由WallpaperService引擎提供的非硬件加速画布,结果与我在同一时间做同样的事情时的结果不一样视图的硬件加速画布对象。

这是一个屏幕截图,显示在加速视图画布上绘制圆圈时会发生什么。 https://www.dropbox.com/s/vgvo3l6wz2d1b1c/good.png?dl=0

以下是在手动创建的画布上绘制时发生的情况,与视图无关。 https://www.dropbox.com/s/zuo23z2y7ik2wmg/bad.png?dl=0

虽然我知道在使用硬件加速或不使用硬件加速时会出现明显的差异,但似乎无法捕获加速画布的渲染外观,而无需通过绘图在软件中重新渲染它缓存,不起作用。如何按原样捕获渲染视图?

写完这篇文章后不久,我注意到只是注释掉设置OVERLAY Xfermode的线条消除了在加速或非加速画布上绘图之间的差异,但这不是一个解决方案。删除OVERLAY模式会产生与我想要捕获的效果完全不同的效果。

0 个答案:

没有答案