¿Convertir una vista a mapa de bits sin mostrarla en Android?


Voy a tratar de explicar lo que exactamente tengo que hacer.

Tengo 3 pantallas separadas dicen A,B,C. Hay otra pantalla llamada decir pantalla de inicio donde todas las 3 pantallas de mapa de bits deben mostrarse en la vista de galería y el usuario puede seleccionar en qué vista quiere ir.

He podido obtener los mapas de bits de todas las 3 pantallas y mostrarlos en la vista de galería colocando todo el código solo en la actividad de la pantalla de inicio. Ahora, esto ha complicado mucho el código y me gustaría simplifícalo.

Entonces, puedo llamar a otra actividad desde la pantalla de inicio y no mostrarla y simplemente obtener el mapa de bits de esa pantalla. Por ejemplo, digamos que solo llamo a la pantalla de inicio y llama a la Actividad A, B, C y ninguna de las Actividades de A, B, C se muestran. Solo da el mapa de bits de esa pantalla por getDrawingCache (). Y luego podemos mostrar esos mapas de bits en la vista de galería en pantalla de inicio.

Espero haber explicado el problema muy claramente.

Por favor, hágamelo saber si esto es realmente posible.

Author: Raghav Sood, 2010-05-10

6 answers

Hay una manera de hacer esto. tienes que crear un mapa de bits y una vista Canvas y call.dibujar(lienzo);

Aquí está el código:

public static Bitmap loadBitmapFromView(View v) {
    Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
    Canvas c = new Canvas(b);
    v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
    v.draw(c);
    return b;
}

Si la vista no se muestra antes de que el tamaño de la misma será cero. Es posible medirlo así:

if (v.getMeasuredHeight() <= 0) {
    v.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    v.draw(c);
    return b;
}

EDITAR: de acuerdo con este post, Pasar WRAP_CONTENT como valor a makeMeasureSpec() no hace ningún bien (aunque para algunas clases de vista funciona), y el método recomendado es:

// Either this
int specWidth = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST);
// Or this
int specWidth = MeasureSpec.makeMeasureSpec(0 /* any */, MeasureSpec.UNSPECIFIED);
view.measure(specWidth, specWidth);
int questionWidth = view.getMeasuredWidth();
 174
Author: Simon Heinen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:37

Aquí está mi solución:

public static Bitmap getBitmapFromView(View view) {
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(returnedBitmap);
    Drawable bgDrawable =view.getBackground();
    if (bgDrawable!=null) 
        bgDrawable.draw(canvas);
    else 
        canvas.drawColor(Color.WHITE);
    view.draw(canvas);
    return returnedBitmap;
}

Disfruta :)

 23
Author: Gil SH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-07 08:12:45

Prueba esto,

        /**
         * Draw the view into a bitmap.
         */
        public static Bitmap getViewBitmap(View v) {
            v.clearFocus();
            v.setPressed(false);

            boolean willNotCache = v.willNotCacheDrawing();
            v.setWillNotCacheDrawing(false);

            // Reset the drawing cache background color to fully transparent
            // for the duration of this operation
            int color = v.getDrawingCacheBackgroundColor();
            v.setDrawingCacheBackgroundColor(0);

            if (color != 0) {
                v.destroyDrawingCache();
            }
            v.buildDrawingCache();
            Bitmap cacheBitmap = v.getDrawingCache();
            if (cacheBitmap == null) {
                Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException());
                return null;
            }

            Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

            // Restore the view
            v.destroyDrawingCache();
            v.setWillNotCacheDrawing(willNotCache);
            v.setDrawingCacheBackgroundColor(color);

            return bitmap;
        }
 20
Author: Dwivedi Ji,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-30 05:59:51

Sé que esto puede ser un problema rancio, pero estaba teniendo problemas para conseguir cualquiera de estas soluciones para trabajar para mí. Específicamente, descubrí que si se realizaban cambios en la vista después de que se inflara, esos cambios no se incorporarían al mapa de bits renderizado.

Aquí está el método que terminó funcionando para mi caso. Con una advertencia, sin embargo. antes de llamar getViewBitmap(View) inflé mi vista y le pedí que diseñara con dimensiones conocidas. Esto era necesario ya que mi diseño de vista haría cero altura / ancho hasta que el contenido se colocó en el interior.

View view = LayoutInflater.from(context).inflate(layoutID, null);
//Do some stuff to the view, like add an ImageView, etc.
view.layout(0, 0, width, height);

Bitmap getViewBitmap(View view)
{
    //Get the dimensions of the view so we can re-layout the view at its current size
    //and create a bitmap of the same size 
    int width = view.getWidth();
    int height = view.getHeight();

    int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
    int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);

    //Cause the view to re-layout
    view.measure(measuredWidth, measuredHeight);
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

    //Create a bitmap backed Canvas to draw the view into
    Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);

    //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
    view.draw(c);

    return b;
}

La" salsa mágica " para mí se encontró aquí: https://groups.google.com/forum/#! topic / android-developers / BxIBAOeTA1Q

Salud,

Levi

 10
Author: levigroker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-18 18:00:35

Espero que esto ayude

View view="some view instance";        
view.setDrawingCacheEnabled(true);
Bitmap bitmap=view.getDrawingCache();
view.setDrawingCacheEnabled(false);
 2
Author: Akhilesh Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-09 09:00:41
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
 -3
Author: Ashutosh Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 05:58:43