2

如何使用给定的 URI 从 sdcard 获取缩略图?我曾尝试使用 bitmapfactory,但性能不佳或 OutOfMemoryError 我要将缩略图放入包含大量数据的列表视图中,我应该使用缩略图还是任何建议?如果要使用缩略图,那么该怎么做...?

在此先感谢您的帮助

4

4 回答 4

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 回答
0

使用ThumbnailUtils类获取图像/视频的缩略图。

于 2012-07-02T08:46:07.597 回答
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 回答