Guardar hardware acelerado android lienzo como mapa de bits

Actualmente estoy dibujando directamente en el objeto Canvas proporcionado al método onDraw de mi vista. Este lienzo es hardware acelerado. En particular, estoy dibujando varios círculos usando sombreadores RadialGradient con el modo OVERLAY PorterDuff. Sin embargo, cuando intento aplicar el mismo procedimiento de dibujo a un lienzo que creo manualmente, no obtengo los mismos resultados. Creo que esto es porque el objeto de lienzo creado para el mapa de bits no es hardware acelerado.

El código parece algo así para la vista:

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); } } 

Hasta este punto, todo está bien y bien. Los círculos se dibujan como se espera en el lienzo acelerado por hardware.

Sin embargo, si hago esto:

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

o alguna variación de esto:

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

o si intento dibujar con los mismos shaders y pintar banderas en, por ejemplo, el lienzo acelerado no hardware proporcionado por el motor WallpaperService, los resultados no son exactamente iguales a los que tenían cuando hice lo mismo en el hardware acelerado lienzo objeto de la vista.

Aquí hay una captura de pantalla que muestra lo que ocurre cuando los círculos se dibujan en un lienzo de vista acelerada. https://www.dropbox.com/s/vgvo3l6wz2d1b1c/good.png?dl=0

Esto es lo que sucede cuando se dibuja sobre un lienzo creado manualmente, no asociado con una vista. https://www.dropbox.com/s/zuo23z2y7ik2wmg/bad.png?dl=0

Aunque entiendo que hay diferencias significativas a esperar cuando se dibuja con aceleración de hardware o no, parece que no hay forma de capturar incluso la apariencia renderizada del lienzo acelerado sin tener que volver a representarlo en el software a través de la caché de dibujo, que no funciona. ¿Cómo puedo capturar la vista renderizada tal como está?

Poco después de escribir esto, me di cuenta de que simplemente comentar la línea que establece el OVERLAY Xfermode elimina la diferencia entre el dibujo en un lienzo acelerado o no acelerado, pero esto no es una solución. Eliminar el modo OVERLAY produce un efecto completamente diferente al que intento capturar.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.