使用URI从sdcard获取缩略图

时间:2012-07-02 08:36:56

标签: android image listview uri thumbnails

如何使用给定的URI从SD卡获取缩略图? 我已经尝试过使用bitmapfactory,但性能不好或者OutOfMemoryError 我将使用大量数据将缩略图放到列表视图中 我应该使用缩略图还是任何建议? 如果要使用缩略图,那么该怎么做......?

提前感谢您的帮助

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分:0)

使用ThumbnailUtils课程获取图片/视频的大拇指。

答案 2 :(得分: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。

答案 3 :(得分: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;

}