2

How to get thumbnails from sdcard with the given URI ?? I have tried using bitmapfactory but the performance is bad or OutOfMemoryError I am going to put the thumbnails to the listview with a lot of data should I use thumbnails or any suggestions? if thumbnails are to be used then how to do it...?

Thanks in advance for the help

Sieryuu
  • 1,510
  • 2
  • 16
  • 41
  • Have you tried this http://stackoverflow.com/questions/1069095/how-do-you-create-a-thumbnail-image-out-of-a-jpeg-in-java – UdayaLakmal Jul 02 '12 at 08:48

4 Answers4

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);
unexpectedvalue
  • 6,079
  • 3
  • 38
  • 62
  • Thanks for your answer, btw i have tried with your coding the load is faster than my previous code, but the scroll of the listview is not smooth . – Sieryuu Jul 02 '12 at 09:04
0

Use ThumbnailUtils class to get the thumb of the image/video.

Vineet Shukla
  • 23,865
  • 10
  • 55
  • 63
0

The following method can be used to get the thumbnail of image:

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

And always call bitmap.recycle() method after using bitmaps. It will clear the bitmap from memory. Also avoid memory leaks in your code. This will solve your OOME.

Shrikant Ballal
  • 7,067
  • 7
  • 41
  • 61
  • the coding works, but the scroll isn't that smooth even with 10 items on my listview. i have put the IMAGE MAX SIZE to 100, but still dont solved the performance problem. oh and i use recycle on my custom adapter, and got `runtime exception : canvas trying to use a recycled bitmap` – Sieryuu Jul 02 '12 at 09:50
  • check if(bitmap != null) before recycling it. Which android version are you using? if its 3.0 and above then provide hardwareAccelerated = true for listView in xml – Shrikant Ballal Jul 02 '12 at 10:15
0

Try with this code, it fix the Out of memory error. Change the height and width as yours. Here intent_data2 is file path.

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;

}

Aerrow
  • 12,086
  • 10
  • 56
  • 90