2015-05-03 25 views
5

sto cercando di mostrare immagini in una visualizzazione a schermo intero e utilizzando il seguente codice:Scarica immagine e ridimensionare per evitare errori OOM, Picasso in forma() distorce immagine

// Target to write the image to local storage. 
Target target = new Target() { 
    // Target implementation. 
} 

// (1) Download and save the image locally. 
Picasso.with(context) 
     .load(url) 
     .into(target); 

// (2) Use the cached version of the image and load the ImageView. 
Picasso.with(context) 
     .load(url) 
     .into(imgDisplay); 

Questo codice funziona bene sui cellulari di nuova generazione, ma su telefoni con VM da 32 MB, ho problemi di memoria. Così ho provato a cambiare (2) a:

Picasso.with(context) 
     .load(url) 
     .fit() 
     .into(imgDisplay); 

Ciò ha provocato immagini distorte. Dal momento che non so le dimensioni dell'immagine finché non viene scaricato, non è possibile impostare le dimensioni ImageView, e quindi l'immagine viene ridimensionata senza alcuna considerazione di proporzioni al mio ImageView:

<ImageView 
    android:id="@+id/imgDisplay" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:scaleType="fitCenter" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" /> 

Qual è la miglior modo per gestire questa situazione? Le mie immagini originali hanno una larghezza massima di 768 e un'altezza di 1024, e voglio ridiscutere quando gli schermi sono molto più piccoli di questo. Se provo a utilizzare resize(), il mio codice diventa complicato, in quanto devo attendere (1) per completare il download e quindi aggiungere lo resize() in (2).

Suppongo che le trasformazioni non siano d'aiuto in questo caso, poiché l'input per public Bitmap transform(Bitmap source) avrà già la bitmap grande che mi causerà l'esaurimento della memoria.

risposta

5

È possibile combinare fit() con centerCrop() o centerInside(), a seconda di come si desidera che l'immagine per misura il vostro View:

Picasso.with(context) 
    .load(url) 
    .fit() 
    .centerCrop() 
    .into(imgDisplay); 

Picasso.with(context) 
    .load(url) 
    .fit() 
    .centerInside() 
    .into(imgDisplay); 
+1

Questo funziona! Sono stato buttato fuori dalla documentazione che mi ha fatto pensare che 'centerInside()' deve essere usato con 'resize()' [Da Doc] (https://square.github.io/picasso/javadoc/com/ squareup/picasso/RequestCreator.html # centerInside--): 'Centra un'immagine all'interno dei limiti specificati da ridimensiona (int, int). Questo ridimensiona l'immagine in modo che entrambe le dimensioni siano uguali o inferiori ai limiti richiesti. " – wislo

+0

Lo so, è un errore comune e i documenti non sono chiari. Per tua informazione, 'fit()' aspetta solo che la Vista ottenga le sue dimensioni, ma in realtà non fa nulla ** ridimensiona ** l'immagine in quella dimensione – Sebastiano

+0

[fit()] (https://square.github.io/picasso /javadoc/com/squareup/picasso/RequestCreator.html#fit--) dice "Tentativo di ridimensionare l'immagine per adattarla esattamente ai limiti di ImageView di destinazione." Quindi non ridimensiona la bitmap? Sono un po 'confuso dal tuo ultimo commento. Voglio assicurarmi che il downsampling sia fatto e carico la bitmap correttamente dimensionata per evitare sprechi di memoria. Qual è il modo migliore per farlo? A proposito, ho un altro 'View' nella mia app che ha una dimensione NxN fissa in cui ho usato' fit() 'insieme a' centerCrop() 'assumendo che il downsampling possa accadere. – wislo