5

InputStream から 1 つの画像のサイズを変更しようとしているので、画像を Bitmap オブジェクトにロードするときに Strange out of memory issueのコードを使用しますが、このコードが常に画像なしで Drawable を返す理由がわかりません。

これはうまくいきます:

private Drawable decodeFile(InputStream f){
    try {
        InputStream in2 = new BufferedInputStream(f);
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=2;
        return new BitmapDrawable(BitmapFactory.decodeStream(in2, null, o2));
    } catch (Exception e) {
        return null;
    }
}

これは機能しません:

private Drawable decodeFile(InputStream f){
    try {
        InputStream in1 = new BufferedInputStream(f);
        InputStream in2 = new BufferedInputStream(f);
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in1,null,o);

        //The new size we want to scale to
        final int IMAGE_MAX_SIZE=90;

        //Find the correct scale value. It should be the power of 2.
        int scale = 2;
        if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
            scale = (int)Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / 
               (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inJustDecodeBounds = false;
        o2.inSampleSize=scale;
        return new BitmapDrawable(BitmapFactory.decodeStream(in2, null, o2));
    } catch (Exception e) {
        return null;
    }
}

あるオプションが他のオプションに影響を与えるのはなぜですか? 2 つの異なる InputStream と Options を使用すると、どのように可能になりますか?

4

2 に答える 2

8

実際には2つの異なるものがありますが、 は のラッパーにすぎないためBufferedInputStream、内部的には1つのInputStreamオブジェクトのみを使用します。BufferedInputStreamInputStream

したがって、同じストリームで 2 回メソッドを呼び出すことはできません。2 回BitmapFactory.decodeStream目はストリームの先頭からデコードを開始しないため、間違いなく失敗します。ストリームがサポートされている場合は、ストリームをリセットするか、再度開く必要があります。

于 2012-10-11T15:24:20.493 に答える
1

これはうまく機能する私のコードです。これが役立つことを願っています

//Decode image size
    BitmapFactory.Options optionsIn = new BitmapFactory.Options();
    optionsIn.inJustDecodeBounds = true; // the trick is HERE, avoiding memory leaks
    BitmapFactory.decodeFile(filePath, optionsIn);

    BitmapFactory.Options optionsOut = new BitmapFactory.Options();
    int requiredWidth = ECameraConfig.getEntryById(Preferences.I_CAMERA_IMAGE_RESOLUTION.get()).getyAxe();
    float bitmapWidth = optionsIn.outWidth;
    int scale = Math.round(bitmapWidth / requiredWidth);
    optionsOut.inSampleSize = scale;
    optionsOut.inPurgeable = true;//avoiding memory leaks
    return BitmapFactory.decodeFile(filePath, optionsOut);

そして、2 つの InputStream は必要ないと思います。

于 2012-10-11T15:17:06.813 に答える