L’uso ottimale di BitmapFactory.Le opzioni.inSampleSize di velocità

Grazie a Schermvlieger per chiedere questo domanda su anddev.org,

Sto solo copiando la sua domanda COSÌ come nessuno ha risposto in un altro sito e anche io sto affrontando lo stesso problema.

Mi chiedevo che cosa sarebbe l’ottimale utilizzo di BitmapFactory.Options.inSampleSize per quanto riguarda la velocità di visualizzazione dell’immagine.
La documentazione accenna all’uso di valori che sono potenze di 2, così mi trovo a lavorare con 2, 4, 8, 16, etc.

Le cose che mi chiedo sono:

  1. Devo ricampionare alla dimensione più piccola che è ancora più grande la risoluzione dello schermo, o devo campione fino alla dimensione sufficiente per evitare un OutOfMemoryError?
  2. Come si potrebbero calcolare la dimensione massima di un’immagine che potrebbe ancora essere visualizzati senza esaurire la memoria? La profondità di colore dell’immagine gioca un ruolo importante, e la profondità del display?
  3. È efficiente per visualizzare le immagini tramite due meccanismi (BitmapFactory per file di grandi dimensioni, setImageURI() per quelli più piccoli) sto utilizzando un ImageSwitcher la strada.
  4. Sarebbe di aiuto per creare il Bitmap, BitmapFactory.Options e inTempStorage all’inizio dell’applicazione o la creazione di loro solo al volo, quando necessario?

 

3 Replies
  1. 11

    Si dovrebbe sempre cercare di carico e pre-ridimensionare le immagini in modo che siano il più vicino possibile alla loro finale visualizzato dimensioni. Il ridimensionamento delle immagini durante il disegno è estremamente costoso e dovrebbe essere evitato a tutti i costi.

    Considerando il costo della memoria di un’immagine, sì, il colore-deptch gioca un ruolo molto importante. Immagini in ALPHA_8 formato 1 byte per pixel, le immagini in RGB_565 o ARGB_4444 l’utilizzo di 2 byte per pixel e immagini in ARGB_8888 4 byte per pixel. La profondità del display non importa affatto. Si dovrebbe sempre cercare di utilizzare ARGB_8888 per ottenere la migliore qualità possibile, ma 565 può essere sufficiente se la tua immagine è opaco.

    • Quando si dice che “il ridimensionamento delle immagini durante il disegno è estremamente costoso” questo include opzioni.inSampleSize anche?
    • inSampleSize viene utilizzato per scalare le immagini in fase di caricamento, non a disegnare tempo. Si tratta di un ottimo modo per fattori di divisione di immagini.
    • Stiamo usando ARGB_8888 , che è una produzione molto torbido immagine sul Samsung Galaxy Note 2, ma ha funzionato bene su un altro dispositivo, bring it on ARGB_4444 va in crash l’app su Samsung Galaxy Note 2 e il Pad 3110, a causa outOfMemoryError. Potete aiutarci a risolvere questa cosa.
  2. 4

    Hai fatto delle buone domande , ma tutto dipende dalle tue esigenze e la quantità di memoria in uso.
    Mi consiglia di controllare questo link per molti consigli riguardo bitmap: http://developer.android.com/training/displaying-bitmaps/index.html .

    In breve , si dovrebbe considerare la memorizzazione nella cache , il downsampling , e l’utilizzo di una buona, abbastanza formato bitmap ogni volta che si può.

    Ecco le mie risposte alle tue domande:

    1. Perché non entrambi? se pensi che ci potrebbe essere OOM , tenta di riciclare vecchi e inutilizzati bitmap e quindi controllare di nuovo .

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

      larghezza*altezza*bytesPerPixel

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

    3. Mai usato setImageURI , quindi non ti posso aiutare con questo. Io suggerisco di scaricare le immagini in un thread in background (utilizzando asyncTask è un modo per farlo) e mostrando loro quando è pronto.

    4. Se ci sono solo pochi che si sa che non prendere un sacco di memoria , credo che sia ok. Penso ancora che la cache potrebbe essere migliore.

  3. 3

    Qui è possibile chiamare il metodo definito dall’utente shrinkmehtod che effettivamente inviare la stringa di percorso del file e l’altezza e la larghezza ridurre l’immagine di metodo.

     Bitmap bit=shrinkmethod(arrpath1[position], 100, 100);
    
    
                //iv.setImageURI(Uri.parse(arrpath1[position]));
                iv.setImageBitmap(bit);

    Questo è definito dall’utente metodo 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 vi aiuterà a ridurre la dimensione.

Lascia un commento