3

We are working on a Android app that captures images and converts the same to Bitmap to be posted to a Rest service.

While creating the Bitmap we have BitmapFactory.Options.isSample Size configured to value of 4 and this works fine on all device except for HTC One. The image in HTC one is distorted.

When we change the value to 1 it shows a good image on HTC one but the application crashes on all other devices because of Memory issues.

The issue is related to Heap size available.

  1. What is the reason that HTC one shows a distorted image on HTC one.
  2. Why is application crashing on S3 which also has the same build version of 16 but crashes due to heap size unavailability.
  3. Why does all lower version phone like droid works fine for sample size of 4.
  4. Whats the best way to check available memory space for an app and use the available for working with BITMAP.

When we configure android:largeHeap in manifest file this seems to work but it does not seem to be a dependable solution.


I was able to find the size of the picture taken using camera parameters and then arrive at optimal sample size of bitmap. The below code solves issue. But is it right way of doing or should i need to compute sample size too instead of going with 1 and 4.

private Bitmap createImaegBitmap(byte[] data)
    {
        BitmapFactory.Options opt;

        opt = new BitmapFactory.Options();
        opt.inTempStorage = new byte[16 * 1024];
        Parameters parameters = ((ReceiptCollection)getApplication()).getParams();
        Size size = parameters.getPictureSize();

        int height11 = size.height;
        int width11 = size.width;
        float mb = (width11 * height11) / 1024000;

        if (mb > 4f)
            opt.inSampleSize = 4;
        else if (mb > 3f)
            opt.inSampleSize = 1;
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,opt);
        return bitmap;
    }
Yoni
  • 1,346
  • 3
  • 16
  • 38
Harshjags
  • 163
  • 1
  • 2
  • 12
  • The image produced on the HTC one looks distorted on the device itself (could be a layout issue) or the actual produced jpg/png image is distorted when viewed with some kind of viewer? – zapl Aug 14 '13 at 22:10
  • We can view the image posted by the service on a browser and its as bad as the image i see in the preview of my app. – Harshjags Aug 14 '13 at 22:29

1 Answers1

4

look:
http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html

1: because... Direct FROM DOC: If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value <= 1 is treated the same as 1. Note: the decoder uses a final value based on powers of 2, any other value will be rounded down to the nearest power of 2.

2:My guess is because not all the devices have the same memory available. 3: you need to calculate the sample size no just set a number...

2,3: all devices have different cameras resolution.

to work on this issue read this: http://developer.android.com/training/displaying-bitmaps/index.html

    public static Bitmap lessResolution(String filePath) {
    int reqHeight = 120;
    int reqWidth = 120;
    BitmapFactory.Options options = new BitmapFactory.Options();

    // First decode with inJustDecodeBounds=true to check dimensions
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filePath, options);

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

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(filePath, options);
}

private static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {

    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

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

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
}
Tobiel
  • 1,543
  • 12
  • 19
  • Thanks for your reply i have updated code in my question but as you mentioned i am finding sample size using camera params but still choosing between 1 and 4 or is it better to completely go with your solution. – Harshjags Aug 14 '13 at 23:32
  • Depends of your needs but keep in mind that insample size is used to avoid the Out of memory when you are working with images of high resolution... sometimes the resolution of a image is too big, reduce the image resolution to 1/4 is not enough. Is not a correct way delimit the value that insample size can have.. – Tobiel Aug 14 '13 at 23:55
  • Gotchu. I would try to compute the sample size based on your algorithm. – Harshjags Aug 15 '13 at 00:17