4

I Need to Convert Bitmap to Byte Array Inorder to Upload to server i was able to achieve the same by converting Bitmap to Byte Array and again converting it to Base 64 String by following instructions here it worked well but in the worst case in my galaxy s2 mobile if the image size is of 6MB with 72 Pixels/Inch Resolution it is occupying around 600MB of RAM and app getting crash with OutOfMemoryException, i tried to upload by compressing the bitmap it worked fine but in my project requirement i need to upload the image as is i.e. with out any compression the original image

please help me how to achieve this whether it is possible or not

Thanks in Advance

Community
  • 1
  • 1
Software Sainath
  • 1,040
  • 2
  • 14
  • 39

2 Answers2

0

For uploading convert to jpeg stream

BufferedStream bs = //...

then call bitmap.compress("JPEG", 0, length, bs)

convert bs to array ad upload that to server

InnocentKiller
  • 5,234
  • 7
  • 36
  • 84
Pulkit Sethi
  • 1,325
  • 1
  • 14
  • 22
0

Android application allocations memory heap is something limited. especially on low ram memory devices.

you are doing two different common mistakes:

  • first: regarding the upload issue - you are holding Bitmap object of a full size image (probably captured with the camera) . this is mistake at the first place. if you have to show on the user interface the captured image - you should load scaled version bitmap according to the required display size(the ImageView width and height..) from the captured image file that just captured and created:

    public static Bitmap getSampleBitmapFromFile(String bitmapFilePath, int reqWidth, int reqHeight) {
    try {
        File f = new File(bitmapFilePath);
        ExifInterface exif = new ExifInterface(f.getPath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    
        int angle = 0;
    
        if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
            angle = 90;
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
            angle = 180;
        } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
            angle = 270;
        }
    
        Matrix mat = new Matrix();
        mat.postRotate(angle);
    
        // calculating image size
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f), null, options);
    
        int scale = calculateInSampleSize(options, reqWidth, reqHeight);
    
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
    
        Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        Bitmap correctBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);
    
        return correctBmp;
    } catch (IOException e) {
        Log.e(TAG, "cant butmaputils.getSampleBitmapFromFile failed with IO exception: ", e);
        if (e != null)
            e.printStackTrace();
    } catch (OutOfMemoryError oom) {
        Log.e(TAG, "cant butmaputils.getSampleBitmapFromFile failed with OOM error: ");
        if (oom != null)
            oom.printStackTrace();
    } catch (Exception e) {
        Log.e(TAG, "cant butmaputils.getSampleBitmapFromFile failed with exception: ", e);
    }
    Log.e(TAG, "butmaputils.getSampleBitmapFromFilereturn null for file: " + bitmapFilePath);
    return null;
     }
    
    
    
    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) {
    
        // 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;
    }
    

by that alone - you reduce dramatically the pressure on your memory allocation heap, because instead of allocation (for example) 1080x1920 integers, you could allocate just 100x200 if that's your imageView screen dimentions.

  • second: uploading to server: you should upload to your server a direct stream from the large original file instead of loading it to memory as Bitmap + decode it to base 64 or. the best way to do it is by using Multipart Entity.

using this approch, not limiting you at all, and even if you want to upload 100M-1000M file - it does not matters, and don't have impact on the memory allocation heap.

for more reading, I recommend you to read - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Community
  • 1
  • 1
Tal Kanel
  • 10,475
  • 10
  • 60
  • 98