12
votes

Android: bitmapfactory.decodebyteArray donne pixelated bitmap

Je travaille sur une application Android qui affiche des photos téléchargées à partir de Flickr. J'obtienne un objet bitmap à partir d'un tableau d'octets, qui est lue à son tour de l'URL flickr correspondante, comme suit: xxx pré>

i puis dessinez le bitmap sur une toile dans la méthode de la veille Objet: P>

Bitmap loadPhotoBitmap(URL url) {
    Bitmap bitmap = null;
        InputStream in = null;
        BufferedOutputStream out = null;

        try {

            FileOutputStream fos = new FileOutputStream("/sdcard/photo-tmp.jpg");
            BufferedOutputStream bfs = new BufferedOutputStream(fos);

            in = new BufferedInputStream(url.openStream(),
                    IO_BUFFER_SIZE);

            final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
            out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
            copy(in, out);                    
            out.flush();
            final byte[] data = dataStream.toByteArray();

            bfs.write(data, 0, data.length);
            bfs.flush();

            BitmapFactory.Options opt = new BitmapFactory.Options();
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);

        } catch (IOException e) {
            android.util.Log.e(LOG_TAG, "Could not load photo: " + this, e);
        } finally {
            closeStream(in);
            closeStream(out)
            closeStream(bfs);
        }

        return bitmap;
    }

private static void copy(InputStream in, OutputStream out) throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    while ((read = in.read(b)) != -1) {
        out.write(b, 0, read);
    }
}

private static void closeStream(Closeable stream) {
    if (stream != null) {
        try {
            stream.close();
        } catch (IOException e) {
            android.util.Log.e(LOG_TAG, "Could not close stream", e);
        }
    }
}


3 commentaires

J'ai pris la liberté d'inliquer les images, car cela rend généralement la question plus agréable et plus facile à lire.


Avez-vous déjà trouvé une solution de contournement pour cela? J'ai essayé les suggestions, mais pas de chance. C'est super gênant.


En tant que note de bas de page, n'oubliez pas que JPEG n'est pas sans perte dans l'environnement Android. Bien qu'il soit soutenu, il est découragé en faveur de PNG.


3 Réponses :


3
votes

Écrivez les octets bruts récupérés de l'URL à /SDCARD/TMP.JPG et affichez sur votre PC.

Les images JPEG sont comprimées dans des tuiles 8x8 (ou 16x16). La «pixelation» comme vous le décrivez est réellement dans ces carreaux, suggérant que l'image «mauvaise» est une JPEG plus agressivement comprimée que l'autre.

Je prévois donc que le problème réel est que l'image en cours de téléchargement est une version de très bonne qualité, par exemple. Un destiné à la vignette / aperçu des cas d'utilisation.


1 commentaires

Je soupçonnais cela aussi, mais la taille du fichier réelle de la "mauvaise" image est d'environ 18% plus grand que le "bon". Étrangeté.



4
votes

OK, donc je l'obtiens enfin: il semble que mon réseau mobile ait une compression d'image pour enregistrer la bande passante.

D'où une image téléchargée à partir de mon téléphone est de qualité inférieure à celle de la même image téléchargée à partir de mon ordinateur.

C'est une bummer pour mon application, mais je ne suppose pas que je ne puisse rien faire à ce sujet. Soupir.

Merci encore pour votre contribution!

meilleur, Michael.


3 commentaires

Il pourrait également être invité par les en-têtes HTTP - Facebook lui-même pourrait fournir des images de qualité médiocre pour les téléphones mobiles. Modifiez les en-têtes avant d'envoyer - essentiellement, supprimez-les!


Vous pouvez essayer de définir les en-têtes HTTP pour accepter-coding gzip. Pas sûr, mais il est possible que cela se contourne la compression de l'image réseau. Voir Stackoverflow.com / Questions / 1573391 / ...


Avez-vous essayé de le confirmer en téléchargeant l'image dans le navigateur? J'ai le même problème, mais si j'ouvre l'image dans le navigateur Web, j'obtiens une image impixnée. Donc, il doit y avoir un moyen d'obtenir la bonne image.



1
votes

Certaines version d'Android ont un bogue dans la classe BitMap et convertissent le bitmap en RGB_565 sur certaines opérations. Cela se manifesterait dans des artefacts similaires à ceux de votre photo. Cela expliquerait également le bandage du ciel bleu. Vous avez également à l'esprit que Android tente de "optimiser" l'image en les convertissant en RGB_565 lors du chargement et même de la compilation des fichiers de ressources. Jeter un coup d'œil à: http://androïd.nakatome.net/2010/04/bitmap-basics.html


0 commentaires