2010-09-13 9 views
8

Dire che ho un bitmap piuttosto grande (cioè non adatto alla memoria della maggior parte dei telefoni) sul disco. Voglio disegnare solo alcune parti dello schermo in un modo che non è ridimensionato (es. inSampleSize == 1)C'è un modo per caricare e disegnare parzialmente una bitmap dal file in Android?

C'è un modo per caricare/disegnare solo la parte che desidero dare un Rect specificando l'area senza caricare l'intero contenuto bitmap?

risposta

9

Sono abbastanza sicuro che questo è possibile in quanto è possibile caricare un file bitmap molto grande in un ImageView senza problemi, quindi ci deve essere una sorta di un modo incorporato per gestire bitmap di grandi dimensioni ... e dopo alcuni tentativi , ho trovato una soluzione:

invece di caricare l'intero bitmap e disegnare manualmente da soli, caricarlo come un Drawable invece:

InputStream mapInput = getResources().openRawResource(
     R.drawable.transit_map); 
_map = Drawable.createFromStream(mapInput, "transit_map"); 

_map.setBounds(0, 0, _mapDimension.width(), _mapDimension.height()); 

sto usando un file di risorse, ma dal momento che possibile utilizzare Drawable.createFromStream per caricare l'immagine da qualsiasi InputStream, dovrebbe funzionare con bitmap arbitrario.

Quindi, utilizzare il metodo Drawable.draw per disegnare sulla tela desiderati in questo modo:

int left = -(int) contentOffset.x; 
int top = -(int) contentOffset.y; 
int right = (int) (zoom * _mapDimension.width() - contentOffset.x); 
int bottom = (int) (zoom * _mapDimension.height() - contentOffset.y); 

_map.setBounds(left, top, right, bottom); 
_map.draw(canvas); 

Come nel caso di cui sopra, si può anche scalare e tradurre il bitmap e manipolando limiti del disegnabili e solo le parti pertinenti della bitmap verranno caricate e disegnate sullo Canvas.

Il risultato è una visualizzazione con zoom a pizzico da un singolo file bitmap da 200 KB. Ho anche provato questo con un file PNG da 22MB e funziona ancora senza lo OutOfMemoryError incluso quando cambia l'orientamento dello schermo.

+0

Nella tua domanda hai dichiarato che l'immagine non si adatta alla memoria. È cambiato? –

+0

No, non è così. È un singolo file PNG, il tutto. – chakrit

1

In generale, ciò non è possibile, soprattutto perché la maggior parte dei formati di immagine sono compressi, quindi non si sa nemmeno quali byte leggere fino a quando non si è estratto il modulo non compresso.

Rompa l'immagine in piccole tessere e carica solo le tessere necessarie per coprire l'area che desideri visualizzare in fase di esecuzione. Per evitare lo scrollamento nervoso, potresti anche voler precaricare le tessere che sono appena fuori dalla vista (quelle che delimitano le tessere visibili) su un thread in background.

3

Si può facilmente essere fatto utilizzando RapidDecoder.

import rapid.decoder.BitmapDecoder; 

Rect bounds = new Rect(10, 20, 30, 40); 
Bitmap bitmap = BitmapDecoder.from("your-file.png") 
          .region(bounds) 
          .decode(); 
imageView.setImageBitmap(bitmap); 

Supporta fino ad Android 2.2 (API Livello 8).

Problemi correlati