12

Flickr からダウンロードした写真を表示する Android アプリに取り組んでいます。次のように、バイト配列からビットマップ オブジェクトを取得します。これは、関連する Flickr URL から読み取られます。

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);

次に、View オブジェクトの onDraw メソッドでキャンバスにビットマップを描画します。

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(bitmap, 0, 0, paint); 

問題は、結果の画像がピクセル化されており、その理由がわかりません。opt オブジェクトと paint オブジェクトのさまざまなバリエーションを試しましたが、うまくいきませんでした。アプリに表示された画像と元の URL の画像の違いは、次のように大まかに示されています。

画像が悪い。左上隅のピクセレーションを参照 http://homepages.inf.ed.ac.uk/s0677975/bad.jpg

良い写真です。これは予想される結果です http://homepages.inf.ed.ac.uk/s0677975/good.jpg

たとえば、左上隅の雲を見て違いを確認してください。

プロジェクト リソースから読み込まれ、同様の方法で描画された JPEG 画像は問題なく表示されることに注意してください。つまり、ピクセレーションはありません。

なぜこれが起こっているのかについて、誰かが私にヒントを与えることができますか?

少し詳しく説明すると、バイト配列は次のように Flickr から取得されます。これは、Romain Guy による Photostream アプリのコードに基づいています。

InputStream 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();

PS: この質問のバリエーションを android.developer Google グループにも投稿しました。


あなたの提案に感謝します - 今、私は本当に困惑しています! 私はあなたが提案したように、ダウンロードしたバイト配列から直接得られた画像が実際にピクセル化されていることを発見しました。ただし、これはまったく同じ URL からダウンロードされ、私のコンピューターでアクセスするとピクセル化されません。対応する Flickr の URL は次のとおりです。

http://farm3.static.flickr.com/2678/4315351421_54e8cdb8e5.jpg

さらに奇妙なことに、携帯電話 (HTC Hero) ではなくシミュレーターで同じアプリを実行すると、ピクセレーションは発生しません。

これはどのように可能ですか?

以下は、URL からビットマップを読み込むために使用するコードです。Romain Guy による Photostream アプリに基づいており、生のバイト配列をファイルに書き込むという Will の提案が組み込まれています。

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);
        }
    }
}

私はここで夢中になっていますか?最高です、マイケル。

4

3 に答える 3

4

わかりました。ようやくわかりました。私のモバイル ネットワークは、帯域幅を節約するために画像圧縮を行っているようです。

したがって、携帯電話からダウンロードした画像は、コンピューターからダウンロードした同じ画像よりも品質が低くなります。

それは私のアプリにとって残念なことですが、それについてできることは何もないと思います。はぁ。

ご意見ありがとうございます。

最高です、マイケル。

于 2010-02-02T16:28:55.623 に答える
3

URL から取得した raw バイトを に書き込み、/sdcard/tmp.jpgPC で表示します。

JPEG 画像は 8x8 (または 16x16) タイルで圧縮されます。あなたが説明した「ピクセレーション」は実際にはこれらのタイルにあり、「悪い」画像は他の画像よりも積極的に圧縮された JPEG であることを示唆しています。

したがって、実際の問題は、ダウンロードされる画像が非常に低品質のバージョンであることであると予想されます。たとえば、サムネイル/プレビューのユースケースを目的としたものです。

于 2010-02-02T12:14:03.410 に答える
1

一部のバージョンのAndroidには、ビットマップクラスにバグがあり、一部の操作でビットマップをRGB_565に変換します。これは、あなたの写真にあるものと同様のアーティファクトに現れます。これはまた、青い空の縞模様を説明するでしょう。また、Androidは、リソースファイルの読み込みやコンパイル時に画像をrgb_565に変換することで、画像を「最適化」しようとすることにも注意してください。ご覧ください:http : //android.nakatome.net/2010/04/bitmap-basics.html

于 2012-01-29T22:51:56.397 に答える