2010-05-10 6 views
96

Je vais essayer d'expliquer ce que je dois faire exactement.Convertir une vue en Bitmap sans l'afficher dans Android?

J'ai 3 écrans séparés disons A, B, C. Il y a un autre écran appelé "HomeScreen" où tous les bitmap 3 écrans doivent être affichés dans la vue Galerie et l'utilisateur peut sélectionner dans quelle vue veut-il aller.

J'ai été en mesure d'obtenir les images bitmap de tous les 3 écrans et de les afficher dans la vue Galerie en plaçant tout le code dans HomeScreen Activity uniquement. Maintenant, cela a beaucoup compliqué le code et j'aimerais le simplifier. Donc, puis-je appeler une autre activité à partir de HomeScreen et ne pas l'afficher et juste obtenir le Bitmap de cet écran. Par exemple, disons que j'appelle simplement HomeScreen et appelle les activités A, B, C et qu'aucune des activités de A, B, C n'est affichée. Il donne juste le Bitmap de cet écran par getDrawingCache(). Et puis nous pouvons afficher ces bitmaps dans la vue Galerie dans HomeScreen.

J'espère avoir expliqué le problème très clairement.

S'il vous plaît laissez-moi savoir si cela est réellement possible.

+4

En fait, j'ai pu fais ceci. – sunil

+1

Je ne suis pas tout à fait sûr, mais je pense que vous ne serez pas capable de faire cela. Le problème est que les activités sont destinées à être affichées à l'utilisateur. Vous pouvez démarrer l'activité et la masquer immédiatement, mais l'activité sera toujours visible pour l'utilisateur pendant une fraction de seconde. Il est montré assez longtemps pour être remarqué, alors que l'écran scintille plusieurs fois rend l'application non professionnelle. Cependant, il peut être possible qu'il existe une commande pour démarrer une activité sans l'afficher; Je n'en connais tout simplement pas un s'il existe. –

+0

Bonjour, Si vous obtenez une solution alors pouvez-vous m'aider? – Kalpesh

Répondre

157

il existe un moyen de le faire. vous devez créer un bitmap et un canevas et appeler view.draw (canvas);

est le code ici:

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 vue n'a pas été affiché avant que la taille de celui-ci sera égal à zéro. Il est possible de le mesurer comme ceci:

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

EDIT: selon this post, passant WRAP_CONTENT comme valeur à makeMeasureSpec() ne pas faire une bonne (bien que pour certaines vue classes, il fonctionne), et recommandé méthode:

// 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(); 
+0

J'ai essayé cela mais tout ce que je reçois est une boîte noire semi-transparente. Ai-je besoin de faire quelque chose sur la vue pour le préparer au dessin bitmap? – Bobbake4

+4

En fait, j'ai dû changer cela en 'v.layout (v.getLeft(), v.getTop(), v.getRight(), v.getBottom());' pour que cela fonctionne correctement, mais merci pour le code :) – triad

+2

J'ai dû utiliser v.getWidth() au lieu de v.getLayoutParams(). width et similaire pour la hauteur. Sinon, travaille maintenant. –

19

voici ma solution:

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

Enjoy :)

+0

+1 merci pour la réponse –

+0

Merci. J'avais des problèmes sur certains appareils si la hauteur dépassait une certaine valeur. Je n'ai pas testé complètement mais cela semble résoudre cela. –

19

Essayez ceci,

/** 
     * Draw the view into a bitmap. 
     */ 
     private 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; 
     } 
+0

Celui-ci a fonctionné hors de la boîte, merci! – muetzenflo

+0

@muetzenflo bienvenue mon pote !!! –

+0

Comment l'utiliser depuis ma classe d'activité principale? – Si8

10

Je sais que cela peut être un problème rassis, mais j'avais des problèmes pour obtenir l'une de ces solutions pour travailler pour moi. Plus précisément, j'ai trouvé que si des modifications étaient apportées à la vue après qu'elle ait été gonflée, ces modifications ne seraient pas incorporées dans le bitmap affiché.

Voici la méthode qui a fini par fonctionner pour mon cas. Avec une mise en garde, cependant. avant d'appeler getViewBitmap(View) j'ai gonflé ma vue et lui ai demandé de mettre en page avec des dimensions connues. Cela était nécessaire car ma disposition de vue rendait la hauteur/largeur nulle jusqu'à ce que le contenu soit placé à l'intérieur.

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 "sauce magique" pour moi a été trouvé ici: https://groups.google.com/forum/#!topic/android-developers/BxIBAOeTA1Q

Cheers,

Levi

1

Hope this helps

View view="some view instance";   
view.setDrawingCacheEnabled(true); 
Bitmap bitmap=view.getDrawingCache(); 
view.setDrawingCacheEnabled(false); 
Questions connexes