Borrar la pintura del lienzo sin borrar la imagen de fondo – Android

Tengo un lienzo con una imagen de fondo. Necesito saber si es posible despejar la pintura de este lienzo para volver a dibujar sin borrar su imagen de fondo. Aquí está mi ejemplo y mis resultados hasta ahora.

JAVA

public void setCanvas() { if(mFile != null && mFile.exists()) { mPictureBitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); mBitmap = Bitmap.createScaledBitmap(mPictureBitmap, mImageView.getWidth(), mImageView.getHeight(), false); mBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true); mCanvas = new Canvas(mBitmap); mImageView.setImageBitmap(mBitmap); mImageView.setOnTouchListener(this); } } private void draw() { mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); // THIS LINE CLEARS int lastIndex = mCordHashMap.size() - 1; int index = 0; for (LinkedHashMap.Entry<String, ArrayList<Circle>> entry : mCordHashMap.entrySet()) { ArrayList<Circle> coords = new ArrayList<Circle>(); coords = entry.getValue(); Path path = new Path(); String key = entry.getKey(); String surface = getSurfaceFromKey(key); changePaint(surface); if (coords.size() < 3) { for (Circle c : coords) { mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCirclePaint); } } else { for (Circle c : coords) { if (c == coords.get(0)) { path.moveTo(c.getmX(), c.getmY()); } else { path.lineTo(c.getmX(), c.getmY()); } } path.close(); mCanvas.drawPath(path, mPaint); mCanvas.drawPath(path, mStrokePaint); } if (index == lastIndex && !mSpecificPathSelected) { for (Circle c : coords) { mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCirclePaint); mCanvas.drawCircle(c.getmX(), c.getmY(), RADIUS, mCircleStrokePaint); } } mImageView.invalidate(); index++; } } 

XML

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ExpandableListView android:id="@+id/surfaceList" android:background="@color/light_grey" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".20" /> <ImageView android:id="@+id/drawContainer" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=".80" android:contentDescription="@string/app_name"/> </LinearLayout> 

Así que el código anterior carga una imagen en mi Canvas . Luego, cada vez que toco el Canvas dibuja un círculo y finalmente un camino entre los círculos. Sin embargo, cuando empiezo a añadir más círculos y caminos, se está redibujando sobre sí mismo, que se ve terrible.

Ahora puedo borrar la pintura de mi lienzo con esta línea.

 mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 

Sin embargo también pierdo el Bitmap que establezco como fondo, y ahora mi fondo es negro. Entonces, ¿cómo puedo mantener mi imagen de fondo, pero claro mi pintura? ¿Es esto posible o tengo que utilizar un trabajo alrededor de como dos Canvas encima de uno a?

Ya he probado lo siguiente, y varias variaciones de la misma.

 1) mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); 2) mCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); mCanvas.drawBitmap(mBitmap, 0, 0, mPaint); 3) mBitmap.eraseColor(Color.TRANSPARENT); mCanvas.drawBitmap(mBitmap, 0, 0, mPaint); 

Cualquier ayuda es apreciada

Por lo que sé, Canvas no incluye capas. Por lo tanto, no puede eliminar una capa (pintura) mientras deja la otra (fondo). Creo que debería estar usando dos lienzos, o incluso el lienzo de pintura y un ImageView para mantener el fondo. Luego, cuando desee exportar la imagen, combine el contenido de la lona con el fondo.

Finalmente lo resolví. Fui capaz de usar dos ImageViews apilados en un RelativeLayout . Apila las ImageViews de imagen una encima de la otra y luego establece ambas imágenes con la misma imagen pero Bitmaps independientes. La parte superior actúa ahora como su primer plano y su fondo actúa como su fondo. Ahora puede dibujar en la parte superior, mientras se borra el fondo y nunca efectúa la inferior. La clave es el atributo yourImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); Que desactiva la aceleración de hardware y permite que su fondo sea realmente transparente. Sin este atributo aplicado a su vista tendrá un fondo negro o blanco que cubre completamente su inferior ImageView lo que lo hace completamente inútil.

XML

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ExpandableListView android:id="@+id/surfaceList" android:background="@color/light_grey" android:layout_width="250dp" android:layout_height="match_parent" /> <ImageView android:id="@+id/background" android:layout_width="match_parent" android:layout_toRightOf="@+id/surfaceList" android:layout_height="match_parent" android:contentDescription="@string/app_name"/> <ImageView android:id="@+id/foreground" android:layout_width="match_parent" android:layout_toRightOf="@+id/surfaceList" android:layout_height="match_parent" android:contentDescription="@string/app_name"/> </RelativeLayout> 

JAVA

 public void setCanvas() { if(mFile != null && mFile.exists()) { // check for null mFirstBitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath()); // get bitmap from directory mSecondBitmap = Bitmap.createScaledBitmap(mPictureBitmap, mImageView.getWidth(), // size bitmap mImageView.getHeight(), false); mSecondBitmap = mSecondBitmap .copy(Bitmap.Config.ARGB_8888, true); // make bitmap mutable so it can be applied to the canvas mFirstBitmap = mSecondBitmap .copy(Bitmap.Config.ARGB_8888, true); // make second bitmap from copy, also mutable mCanvas = new Canvas(mSecondBitmap ); //create your canvas from 2nd bitmap mImageView.setImageBitmap(mSecondBitmap ); // set this imageview to 2nd bitmap mImageView2.setImageBitmap(mFirstBitmap); //set this imageview to 1st bitmap mImageView.setOnTouchListener(this); // set on touch listener mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); // IMPORTANT set hardware acceleration off with this line. Otherwise your view's background will NOT be transparent mImageView.bringToFront(); // bring this imageview to the front, making it your foreground } } 

Espero que esto ahorra a alguien más un montón de tiempo.

Sólo si no está usando imageView hay otra solución, incluso más simple:

Tengo un nuevo Bitmap (mBackgroundBitmap); Nuevo Canvas (mBackgorundCanvas), asignado mBackgroundBitmap a mBackgroundCanvas, y en cada método onDraw en primer lugar i dar mi mapa de bits de fondo:

 canvas.drawBitmap(mBackgroundBitmap, offSetX, offSetY, mBitmapPaint); 

Y justo entonces comienzo a dibujar mi mapa de bits real:

 canvas.drawBitmap(mBitmap, offSetX, offSetY, mBitmapPaint); 

Supongo que no es la solución de memoria eficiente (me refiero a tener dos mapas de bits no es muy guay o agradable, pero luego muchos de nosotros no utiliza imágenes grandes, pero en su lugar (al menos yo) crear mi fondo de un fragmento y luego azulejos en X e Y.

Si mi respuesta es ridícula no me juzgues, soy sólo un novato.

  • ¿Cómo dibujo texto en negrita en un mapa de bits?
  • Conversión de objetos JSON con Bitmaps
  • Color de la máscara de mapa de bits Android, quitar el color
  • Ajuste automático de brillo, contraste y nitidez de una imagen de mapa de bits
  • Creación de un mapa de bits vacío y dibujo a través de lienzo en android
  • Imagen de fondo de Android Widget Cambiar
  • ¿Por qué estoy recibiendo java.io.IOException: Mark ha sido invalidado?
  • Redimensionar bitmap de Android manteniendo relación de aspecto
  • Guardar bitmap en tarjeta SD sin comprimirla en android
  • Opengl es 2.0 dibujar superposición de mapa de bits en vídeo
  • Java Android - volley library - obtener un mapa de bits a través de ImageLoader
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.