2011-01-28 11 views
20

Grazie a Schermvlieger per chiedere this domanda su anddev.org,uso ottimale dei BitmapFactory.Options.inSampleSize per la velocità

che sto semplicemente copiando la sua domanda a così come nessuno ha risposto sull'altro sito e sto anche affrontando lo stesso problema.

Mi chiedevo quale sarebbe l'uso ottimale di BitmapFactory.Options.inSampleSize per quanto riguarda la velocità di visualizzazione dell'immagine.
La documentazione menzioni utilizzando i valori che sono potenze di 2, quindi sto lavorando con 2, 4, 8, 16, ecc

Le cose che mi chiedo circa sono:

  1. Devo ricampionare verso il basso alla dimensione più piccola che è ancora più grande della risoluzione dello schermo, o dovrei campionare fino alle dimensioni quel tanto che basta per evitare un OutOfMemoryError?
  2. Come si calcola la dimensione massima di un'immagine che potrebbe ancora essere visualizzata senza esaurire la memoria? Anche la profondità del colore dell'immagine gioca un ruolo e la profondità del display?
  3. È efficace visualizzare le immagini tramite due meccanismi (BitmapFactory per file di grandi dimensioni, setImageURI() per quelli più piccoli) Sto utilizzando un ImageSwitcher a proposito.
  4. Potrebbe aiutare a creare Bitmap, BitmapFactory.Options e inTempStorage all'inizio dell'applicazione o crearli solo al volo, quando necessario?

risposta

11

Si dovrebbe sempre provare a caricare e pre-scalare le immagini in modo che siano il più vicino possibile alle loro dimensioni finali visualizzate. Ridimensionare le immagini al momento del disegno è estremamente costoso e dovrebbe essere evitato a tutti i costi.

Considerando il costo di memoria di un'immagine, sì, il color-deptch svolge un ruolo molto importante. Le immagini nel formato ALPHA_8 utilizzano 1 byte per pixel, le immagini in RGB_565 o ARGB_4444 utilizzano 2 byte per pixel e le immagini in ARGB_8888 utilizzano 4 byte per pixel. La profondità del display non ha alcuna importanza. Dovresti sempre provare ad usare ARGB_8888 per ottenere la migliore qualità possibile, ma 565 può essere abbastanza buono se la tua immagine è opaca.

+0

Quando si dice che "ridimensionare le immagini al momento del disegno è estremamente costoso" questo include anche options.inSampleSize? – kape123

+0

inSampleSize viene utilizzato per ridimensionare le immagini in fase di caricamento, non in fase di disegno. È un ottimo modo per ordinare le immagini. –

+1

Stiamo usando ARGB_8888, che sta producendo un'immagine molto sfocata su Samsung Galaxy Note 2, ma ha funzionato bene su altri dispositivi, portarlo su ARGB_4444 sta bloccando l'app su Samsung Galaxy Note 2 e Pad 3110, a causa di outOfMemoryError. Puoi aiutarci a risolvere questa cosa. –

3

Qui è possibile chiamare il metodo definito dall'utente shrinkmehtod che invia effettivamente il percorso del file di stringa e l'altezza e la larghezza da ridimensionare al metodo.

Bitmap bit=shrinkmethod(arrpath1[position], 100, 100); 


      //iv.setImageURI(Uri.parse(arrpath1[position])); 
      iv.setImageBitmap(bit); 

Questo è un metodo definito dall'utente per ridurre la dimensione dell'immagine a livello di programmazione.

Bitmap shrinkmethod(String file,int width,int height){ 
     BitmapFactory.Options bitopt=new BitmapFactory.Options(); 
     bitopt.inJustDecodeBounds=true; 
     Bitmap bit=BitmapFactory.decodeFile(file, bitopt); 

     int h=(int) Math.ceil(bitopt.outHeight/(float)height); 
     int w=(int) Math.ceil(bitopt.outWidth/(float)width); 

     if(h>1 || w>1){ 
      if(h>w){ 
       bitopt.inSampleSize=h; 

      }else{ 
       bitopt.inSampleSize=w; 
      } 
     } 
     bitopt.inJustDecodeBounds=false; 
     bit=BitmapFactory.decodeFile(file, bitopt); 



     return bit; 

    } 

Spero che questo ti aiuti a ridurre le dimensioni.

+2

Orginalmente da qui http://madhusudhanrc.blogspot.fr/2012/09/reduce-bitmap-size-using.html – Snicolas

4

Hai fatto delle buone domande, ma tutto dipende dalle tue esigenze e dalla quantità di memoria che usi. Si consiglia di controllare questo collegamento per molti suggerimenti relativi a bitmap: http://developer.android.com/training/displaying-bitmaps/index.html.

In breve, è consigliabile prendere in considerazione il caching, il downsampling e l'utilizzo di un formato bitmap sufficientemente buono ogni volta che è possibile.

Ecco le mie risposte alle tue domande:

  1. Perché non entrambi? se pensi che possa esserci OOM, prova a riciclare vecchie bitmap inutilizzate e poi ricontrolla.

  2. è possibile calcolare la (stimato) dimensioni della bitmap:

    width * height * bytesPerPixel

    dove bytesPerPixel è di solito 4 o 2 (a seconda del formato bitmap).

  3. Mai usato setImageURI, quindi non posso aiutarti in questo. Suggerisco di scaricare le immagini in un thread in background (usando asyncTask è un modo per farlo) e mostrandole quando è pronto.

  4. Se ci sono solo pochi che sai che non ci vorrà molta memoria, credo sia ok. Penso ancora che il caching potrebbe essere migliore.

Problemi correlati