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
- ImageView se estrelló la aplicación
- Visualización de imagen de mapa de bits en Android (OpenCV)
- Obtención de mapa de bits desde SurfaceView personalizado
- Decodificar la matriz de bytes en el mapa de bits que se ha comprimido en Java
- Cómo convertir un dibujable a un mapa de bits?
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
- ImageView: recicla automáticamente el mapa de bits si ImageView no está visible (dentro de ScrollView)
- Fusionar ImageView con una sola imagen de mapa de bits (Android)
- Android: cómo crear un botón sobre Bitmap dinámicamente o botón OVERLAYING?
- Preservar la calidad de la imagen cuando decodifique el flujo en android
- Rellenar los datos en un mapa de bits de Android tan pronto como sea posible desde C
- Cómo cargar una imagen de una URL en un viewpager
- Android fuera de la prevención de la memoria
- ¿Cómo obtener metadatos de una imagen?
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.
- RelativeLayout no maneja "toLeftOf" y / o toRightOf correctamente
- Android mupdf para MIPS y arco x86