web-dev-qa-db-fra.com

afficher d'énormes images en Android

J'ai l'intention d'afficher de très grandes images dans Android.

Ma première solution - pour les fournir au format pdf - échoue car tous les ordinateurs de poche n'ont pas de visionneuse pdf préinstallée, et je ne le fais pas veulent exiger que les utilisateurs en installent un.

J'ai donc un png maintenant (largeur = 3998px hauteur = 2827px) que je veux afficher. J'ai téléchargé cette image pour tester comment elle serait affichée dans la galerie. C'était assez douloureux. Il semble que la galerie ne rend cette image qu'une seule fois, et si je fais un zoom avant, je ne peux pas lire le texte du tout.

J'ai donc écrit un testActivity qui a simplement une ImageView imbriquée dans un LinearLayout. J'ai mis l'image dans le dessin et je l'ai définie comme source d'image d'ImageView. Malheureusement, l'application se bloque immédiatement en raison d'un "

 ERROR/AndroidRuntime(8906): Caused by: Java.lang.OutOfMemoryError: bitmap size exceeds VM budget"  

Je ne m'attendais pas à ce qu'une seule image soit trop grande pourVM's memory. J'ai joué un peu, j'ai réglé la taille de ImageViews sur 3998 & 2827px, placez l'image dans sdCard et lisez-la manuellement avec un fileInputStream.
À ma grande surprise, il montre maintenant mon image, mais si je tourne mon Nexus S horizontal j'obtiens le même OutOfMemoryError comme avant.

Quelqu'un peut-il me signaler la principale différence entre recevoir un bitmap via un FileInputStream ou le définir comme ImageView's la source.

Je ne suis pas non plus en mesure de faire défiler à l'aise avec deux parents scrollViews

Je recherche une solution simple pour afficher ONE large image à la fois avec la capacité de scroll horizontal and vertical tout en pouvant zoomer et dézoomer.

voici un échantillon de l'image que je souhaite afficher enter image description here

29
Rafael T

Je sais que c'est un vieux post mais j'ai passé beaucoup de temps sur ce problème, alors voici ma solution.

Je voulais afficher une image de 2000 × 3000 mais je suis sorti de mémoire ou l'image était trop grande pour être affichée.

Pour commencer, j'obtiens les dimensions de l'image:

o = new BitmapFactory.Options();
o.inJustDecodeBounds=true;
pictures = BitmapFactory.decodeStream(new FileInputStream(f), null, o);

Ensuite, je l'ai découpé en quatre parties et les ai affichées avec quatre ImageViews. J'ai essayé de charger l'image complète et de la couper en quatre (en utilisant BitmapFactory.create(bitmap,int,int,int,int)), mais j'ai de nouveau perdu de mémoire.

J'ai donc décidé d'utiliser du BitMapRegionDecoder:

for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 2; j++) {
        ImageView iv = new ImageView(this);         
        InputStream istream =   null;
        try {
         istream = this.getContentResolver().openInputStream(Uri.fromFile(f));
        } catch (FileNotFoundException e1) {
         e1.printStackTrace();
        }
        BitmapRegionDecoder decoder     =   null;
        try {
        decoder = BitmapRegionDecoder.newInstance(istream, false);
        } catch (IOException e) {
                    e.printStackTrace();
        }
    int nw = (j*width/k);
    int nh = (i*height/k);

    Bitmap bMap = decoder.decodeRegion(new Rect(nw,nh, (nw+width/k),(nh+height/k)), null);    
    iv.setImageBitmap(bMap);

    }
}

Cela a fonctionné.

29
leadersheep

Essayez d'utiliser celui-ci: https://github.com/davemorrissey/subsampling-scale-image-view

Une vue d'image personnalisée pour Android, conçue pour les galeries de photos et affichant des images énormes (par exemple, des cartes et des plans de construction) sans OutOfMemoryErrors. Comprend une prise en charge du zoom, du panoramique, de la rotation et de l'animation, et permet une extension facile afin que vous puissiez ajouter vos propres superpositions et détecter les événements tactiles.

7
Zikkoua

Je sais que c'est une vieille question mais j'ai utilisé TileView pour faire exactement ceci:

https://github.com/moagrius/TileView

7
FRR

Vous pouvez utiliser cette source "facile à intégrer" de l'application WorldMap:

https://github.com/johnnylambada/WorldMap

Cela utilise une image énorme d'une carte du monde et utilise un cache pour afficher une carte.

Pour intégrer, j'ai juste copié tous les fichiers Java (5 je suppose) et utilisé la surfaceView dans mon fichier de disposition. Ensuite, j'ai parcouru la petite méthode OnCreate () d'ImageViewerActivity.Java et utilisé le code dans mon activité (avec une légère altération, selon mon usage personnel).

4
M. Usman Khan

Cet article est une bonne démo pour zoomer une image en utilisant des gestes multi-touch. Il utilise Matrix pour zoomer et effectuer un panoramique sur une image.

2
Ben Lee

Nous devons suivre les étapes suivantes pour supprimer l'exception de mémoire insuffisante lors du chargement d'énormes images:

 1. Read Bitmap Dimensions and Type

 2. Load a Scaled down version into memory

Le Guide du développeur Android définit comment nous y parvenons. Voici le lien

http://developer.Android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap

1
hitesh141

Pour gérer la mise à l'échelle, etc. et utiliser la pleine résolution, vous pouvez utiliser MapView d'OSM (ouvrir le plan des rues) et le fournir avec vos vignettes (au lieu de la carte). Vérifiez ceci: http://www.haakseth.com/?p=

1
M. Usman Khan