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

3 Solutions collect form web for “Borrar la pintura del lienzo sin borrar la imagen de fondo – Android”

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.

  • Android Paint PorterDuff.Mode.CLEAR
  • La clase PdfRenderer de Android produce imágenes de baja calidad
  • Redimensionar bitmap de Android manteniendo relación de aspecto
  • Cambio de mapa de bits Drawable en LayerListDrawable
  • Cómo crear una imagen de perfil circular de facebook
  • ¿Cómo saber cuánto tamaño de montón libre está disponible para bitmap para Android 2. *?
  • Cómo convertir PictureDrawable en mapa de bits
  • Buscando una explicación de post / pre / set Traducir (en el objeto Matrix) y cómo usarlos
  • Aplicación de Android - ¿Cómo guardar un dibujo de mapa de bits en lienzo como imagen? ¿Código de verificación?
  • Bitmap, Bitmap.recycle (), WeakReferences y Garbage Collection
  • Android fuera de la prevención de la memoria
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.