2

指定されたURIでSDカードからサムネイルを取得する方法?? bitmapfactory を使用してみましたが、パフォーマンスが悪いか、OutOfMemoryError です。大量のデータを含むリストビューにサムネイルを配置する予定ですが、サムネイルまたは何か提案を使用する必要がありますか? サムネイルを使用する場合は、どうすればいいですか...?

助けてくれてありがとう

4

4 に答える 4

0

次のメソッドを使用して、画像のサムネイルを取得できます。

private Bitmap getBitmap(String path) {

    Uri uri = getImageUri(path);
    InputStream in = null;
    try {
        final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
        in = mContentResolver.openInputStream(uri);

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(in, null, o);
        in.close();



        int scale = 1;
        while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) {
            scale++;
        }
        Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth       + ", orig-height: " + o.outHeight);

        Bitmap b = null;
        in = mContentResolver.openInputStream(uri);
        if (scale > 1) {
            scale--;
            // scale to max possible inSampleSize that still yields an image
            // larger than target
            o = new BitmapFactory.Options();
            o.inSampleSize = scale;
            b = BitmapFactory.decodeStream(in, null, o);

            // resize to desired dimensions
            int height = b.getHeight();
            int width = b.getWidth();
            Log.d(TAG, "1th scale operation dimenions - width: " + width    + ", height: " + height);

            double y = Math.sqrt(IMAGE_MAX_SIZE
                    / (((double) width) / height));
            double x = (y / height) * width;

            Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x,     (int) y, true);
            b.recycle();
            b = scaledBitmap;

            System.gc();
        } else {
            b = BitmapFactory.decodeStream(in);
        }
        in.close();

        Log.d(TAG, "bitmap size - width: " +b.getWidth() + ", height: " + b.getHeight());
        return b;
    } catch (IOException e) {
        Log.e(TAG, e.getMessage(),e);
        return null;
    }
}

ビットマップを使用した後は、常に bitmap.recycle() メソッドを呼び出します。メモリからビットマップをクリアします。また、コード内のメモリ リークも回避してください。これで OOME が解決されます。

于 2012-07-02T08:48:53.050 に答える
0

このコードを試してみると、メモリ不足エラーが修正されます。高さと幅を自分のものに変更します。ここで、intent_data2 はファイル パスです。

public Bitmap custom_SizedImage(String intent_data2) {
        int targetHeight = 534, targetWidth = 534;
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(intent_data2, options);
        double sampleSize = 0;
        Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math
                .abs(options.outWidth - targetWidth);

        if (options.outHeight * options.outWidth * 2 >= 1638) {
            sampleSize = scaleByHeight ? options.outHeight / targetHeight
                    : options.outWidth / targetWidth;
            sampleSize = (int) Math.pow(2d,
                    Math.floor(Math.log(sampleSize) / Math.log(2d)));
        }
        options.inJustDecodeBounds = false;
        options.inTempStorage = new byte[128];
        while (true) {
            try {
                options.inSampleSize = (int) sampleSize;
                mBitmap = BitmapFactory.decodeFile(intent_data2, options);
                Display display = getWindowManager().getDefaultDisplay();
                int width = display.getWidth();
                int height = display.getHeight();
                int screenDiff = height - width;
                int screenRatio = screenDiff / 3;
                float scaleFactor = mBitmap.getWidth() / width;
                float y_Pos = scaleFactor * screenRatio;
                Matrix matrix = new Matrix();
                matrix.postScale(0.5f, 0.5f);
                croppedBitmap = Bitmap.createBitmap(mBitmap, 0, (int) y_Pos,
                        mBitmap.getWidth(), mBitmap.getWidth(), matrix, true);

                scaledBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
                        Config.RGB_565);

                float ratioX = targetWidth / (float) croppedBitmap.getWidth();
                float ratioY = targetHeight / (float) croppedBitmap.getHeight();
                float middleX = targetWidth / 2.0f;
                float middleY = targetHeight / 2.0f;

                Matrix scaleMatrix = new Matrix();
                scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

                Canvas canvas = new Canvas(scaledBitmap);
                canvas.setMatrix(scaleMatrix);
                canvas.drawBitmap(croppedBitmap,
                        middleX - croppedBitmap.getWidth() / 2, middleY
                                - croppedBitmap.getHeight() / 2, new Paint(
                                Paint.FILTER_BITMAP_FLAG));
                //saveImage(scaledBitmap);

                break;
            } catch (Exception ex) {
                try {
                    sampleSize = sampleSize * 2;
                } catch (Exception ex1) {

                }
            }
        }
        return scaledBitmap;

}

于 2012-07-02T08:49:34.373 に答える
0
 // Parameters
 int w,h;     

 // First only decode image size
 BitmapFactory.Options opt = new BitmapFactory.Options();
 opt.inJustDecodeBounds = true;
 Bitmap bmp = BitmapFactory.decodeFile(file, opt);

 // Decode small enough image
 int heightRatio = (int)opt.outHeight/h;
 int widthRatio = (int)opt.outWidth/w;
 if (heightRatio > 1 || widthRatio > 1)
 {
      if (heightRatio > widthRatio)
           opt.inSampleSize = heightRatio;
      else
           opt.inSampleSize = widthRatio; 
 }

 opt.inJustDecodeBounds = false;
 bmp = BitmapFactory.decodeFile(file, opt);
于 2012-07-02T08:45:51.663 に答える