0

I have an android app in which I give the possibility to whether take a photo or choose it from library. The problem is that taking a photo with the camera works pretty well, however, when I select a photo from the library the app bugs. After checking the size of the photos I find that the size of the selected photos (thumbnails) is very very big that's why the application slows and crashes after a while when I try to store the photo in my database. For example, the size of a photo taken with camera in my app is 129600 bytes, but when I try a second time to load this same photo from library into my app I find that its size is now 8294400 (much bigger) !! which is pretty bizarre !

I am wondering if my way of handling the case of photo selection (case when requestCode == 2) is correct, and if there is an error in my code ?

Here is my full code:

    private void selectImage() {

    final CharSequence[] options = { "Take Photo", "Choose from Gallery","Cancel" };

    AlertDialog.Builder builder = new AlertDialog.Builder(ScrollingActivity.this);
    builder.setTitle("Add Photo!");
    builder.setItems(options, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (options[item].equals("Take Photo"))
            {
                Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(intent, 1);
            }
            else if (options[item].equals("Choose from Gallery"))
            {
                Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, 2);

            }
            else if (options[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == 1) {
            thumbnail = (Bitmap) data.getExtras().get("data");
            System.out.println("Image Byte Count: " + thumbnail.getByteCount()); // prints 129600 Bytes.
        } else if (requestCode == 2) {

            Uri selectedImage = data.getData();
            String[] filePath = { MediaStore.Images.Media.DATA };
            Cursor c = getContentResolver().query(selectedImage,filePath, null, null, null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePath[0]);
            String picturePath = c.getString(columnIndex);
            c.close();
            thumbnail = (BitmapFactory.decodeFile(picturePath));
            System.out.println("Image Byte Count: " + thumbnail.getByteCount()); // prints 8294400 bytes!!!
        }
        renderImage();
    }
}

Thank you in advance for your help !

Othmane
  • 926
  • 1
  • 14
  • 30

1 Answers1

1

I faced the same problem last week and discovered on this forum that there is an option to check the image size without loading it into memory. Have a look at BitmapFactory.options The code below is cut from Stackoverflow.

               Resources res = mContext.getResources();
                int allowedwidth= res.getDimensionPixelSize(R.dimen.albumart_image_width);
                int allowedheight= res.getDimensionPixelSize(R.dimen.albumart_image_height);
                    holder.improfile.setImageBitmap(
                            decodeSampledBitmapFromFile(circlepicture, allowedwidth, allowedheight));
            } catch (Exception e) {
                e.printStackTrace();

    }

public static Bitmap decodeSampledBitmapFromFile(String circlepicture,int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(circlepicture,  options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(circlepicture,  options);
}
public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}
Theo
  • 1,712
  • 14
  • 26
  • Can you please provide me with the link to the original Stackoverflow discussion ? Thanks – Othmane Oct 21 '16 at 02:14
  • Thank you this resolves just some cases when the photos were taken by the app capture image but still gives a huge size for other images. I am still looking for a complete solution ! – Othmane Oct 21 '16 at 03:26
  • Android documentation states the following: inJustDecodeBounds Added in API level 1 boolean inJustDecodeBounds If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels. – Theo Oct 21 '16 at 11:45
  • The code provided in the answer ensures that the image is correctly resized so it can be displayed without an Out Of Memory crash. – Theo Oct 21 '16 at 11:47
  • I've tried different ways in onActivityResult to treat the data object to transform it into a usable bitmap object but still always get a very huge size than when I simply capture a photo directly. No clue why this is happening ! – Othmane Oct 23 '16 at 04:28
  • there are plenty of examples on SO http://stackoverflow.com/questions/4837715/how-to-resize-a-bitmap-in-android – Theo Oct 23 '16 at 14:24