2

I want in my app send photo image to the server. API uses Base64 format of images. I have path to the image/photo and now I want convert this path to the Base64 array.

For load the image I have this code (it´s also resize the image to max size) from here:

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 this is code to send the image:

        image = getBitmap(pathToImage);

        ByteArrayOutputStream stream = new ByteArrayOutputStream();

        String filenameArray[] = fileName.split("\\.");
        String extension = filenameArray[filenameArray.length - 1];

        if (extension.equalsIgnoreCase("jpg")
                || extension.equalsIgnoreCase("jpeg"))
            image.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        else
            image.compress(Bitmap.CompressFormat.PNG, 100, stream);

        image.recycle();
        image = null;

        byte[] byteArray = stream.toByteArray();

        try {
            stream.close();
        } catch (IOException e1) {

        }

        stream = null;

        ByteArrayOutputStream baos = new ByteArrayOutputStream(
                (int) (byteArray.length * 1.5));

        JsonGenerator jgenerator = null;

        try {
            jgenerator = new JsonFactory().createGenerator(baos);

            jgenerator.writeStartObject();
            jgenerator.writeStringField("fileName", fileName);
            // Jackson takes care of the base64 encoding for us
            jgenerator.writeBinaryField("content", byteArray);
            jgenerator.writeEndObject();
            jgenerator.close();

        } catch (JsonGenerationException e) {
        } catch (IOException e) {
        }

        HttpClient httpClient = new DefaultHttpClient();

        HttpPost httppost = new HttpPost(Globals.URL + "/storageUploadFile");

        httppost.setHeader("Token", Globals.Token);
        httppost.setHeader("Content-type",
                "application/json; charset=utf-8");

        httppost.setEntity(new ByteArrayEntity(baos.toByteArray()));

        HttpResponse response;
        try {
            response = httpClient.execute(httppost);

            HttpEntity httpentity = response.getEntity();

            msg = EntityUtils.toString(httpentity);

            jgenerator = null;
            httppost = null;
            httpClient = null;
            httpentity = null;

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }

Sometimes I get an OutOfMemory error in row Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x, (int) y, true); or in row jgenerator.writeBinaryField("content", byteArray);

Can you help me to modify the code to avoid OutOfMemory error? Do you have some tips how to convert image from file to Base64 and send it as HTTPPost?

Community
  • 1
  • 1
Pepa Zapletal
  • 2,879
  • 3
  • 39
  • 69
  • 1
    possible duplicate of [Strange out of memory issue while loading an image to a Bitmap object](http://stackoverflow.com/questions/477572/strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object) – tyczj Aug 12 '14 at 13:49
  • 1
    possible duplicate of [How to load large images in Android and avoiding the out of memory error?](http://stackoverflow.com/questions/21392972/how-to-load-large-images-in-android-and-avoiding-the-out-of-memory-error) – sergej shafarenka Aug 12 '14 at 13:50
  • 1
    Very bad idea to encode images to base64 strings. Makes the whole 30% bigger and forces to keep all in memory. Better look for a server script where you can post the file as is. – greenapps Aug 12 '14 at 18:42
  • @greenapps can you tell me more info about it? what we should use on server side and what I should do in app? Thx. – Pepa Zapletal Aug 13 '14 at 13:18
  • You did not tell what type of server you have. And you did not tell why you would use json to upload a file. If you just look around on this site you will find numerous examples posting an image to a php script. – greenapps Aug 13 '14 at 15:01

1 Answers1

2

Did you try the Picasso library ?

AsyncTask<String,Void,Void> downloadAndResizePictureTask = new AsyncTask<String,Void,Void>(){
    @Override 
    public Void doInBackground(String... params){
       //assuming params[0] is a valid url
       Bitmap bmp = Picasso.with(getActivity()).load(params[0]).resize(150,150).get();
       ByteArrayOutputStream stream = new ByteArrayOutputStream();
       bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
       byte[] byteArray = stream.toByteArray();
       //do what needs to be done to convert to Base64

    }
}
Muhammed Refaat
  • 8,914
  • 14
  • 83
  • 118
Lena Bru
  • 13,521
  • 11
  • 61
  • 126