0

I am new to android. I have created one app to upload an image to server. It works perfectly for small size images but for larger images(>1 MB), this does not work. Here is my function for uploading image

class UploadFile extends AsyncTask<String,String,String>{
        private ProgressDialog pDialog;
        JSONObject jobj = null;
        String json,msg;
        String filepath,dat,remark,hid,pid,form;
        public UploadFile(String filepath,String remark,String dt,
                String hid,String pid, String form) {
            // TODO Auto-generated constructor stub
            this.filepath = filepath;
            this.dat = dt;
            this.remark =remark;
            this.hid=hid;
            this.pid=pid;
            this.form =form;
        }

        protected void onPreExecute() {

            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Uploading Image...Please wait");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();

       }


        @Override
        protected String doInBackground(String... arg0) {


            String fileName = filepath;

              HttpURLConnection conn = null;
              DataOutputStream dos = null;  
              String lineEnd = "\r\n";
              String twoHyphens = "--";
              String boundary = "*****";
              int bytesRead, bytesAvailable, bufferSize;
              byte[] buffer;
              int maxBufferSize = 1 * 1024 * 1024; 
              File sourceFile = new File(filepath); 

              if (!sourceFile.isFile()) {


                   Log.e("uploadFile", "Source File not exist :");


                   return null;

              }
              else
              {
                   try { 

                         // open a URL connection to the Servlet
                       FileInputStream fileInputStream = new FileInputStream(sourceFile);
                       URL url = new URL(upLoadServerUri);

                       // Open a HTTP  connection to  the URL
                       conn = (HttpURLConnection) url.openConnection(); 
                       conn.setDoInput(true); // Allow Inputs
                       conn.setDoOutput(true); // Allow Outputs
                       conn.setUseCaches(false); // Don't use a Cached Copy
                       conn.setRequestMethod("POST");
                       conn.setRequestProperty("Connection", "Keep-Alive");
                       conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                       conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);


                       dos = new DataOutputStream(conn.getOutputStream());

                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"hid\"" + lineEnd);
                       dos.writeBytes(lineEnd);
                       // You can assign values as like follows : 
                       dos.writeBytes(hid);
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + lineEnd);

                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"pid\"" + lineEnd);
                       dos.writeBytes(lineEnd);
                       // You can assign values as like follows : 
                       dos.writeBytes(pid);
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + lineEnd);

                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"form\"" + lineEnd);
                       dos.writeBytes(lineEnd);
                       // You can assign values as like follows : 
                       dos.writeBytes(form);
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + lineEnd);

                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"dt\"" + lineEnd);
                       dos.writeBytes(lineEnd);
                       // You can assign values as like follows : 
                       dos.writeBytes(dat);
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + lineEnd);

                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"remark\"" + lineEnd);
                       dos.writeBytes(lineEnd);
                       // You can assign values as like follows : 
                       dos.writeBytes(remark);
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + lineEnd);


                       dos.writeBytes(twoHyphens + boundary + lineEnd);
                       dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\""+ fileName + "\"" + lineEnd);
                       dos.writeBytes(lineEnd);



                       // create a buffer of  maximum size
                       bytesAvailable = fileInputStream.available(); 
                       bufferSize = Math.min(bytesAvailable, maxBufferSize);
                       buffer = new byte[bufferSize];

                       // read file and write it into form...
                       bytesRead = fileInputStream.read(buffer, 0, bufferSize);  


                       while (bytesRead > 0) {

                         dos.write(buffer, 0, bufferSize);
                         bytesAvailable = fileInputStream.available();
                         bufferSize = Math.min(bytesAvailable, maxBufferSize);
                         bytesRead = fileInputStream.read(buffer, 0, bufferSize);   

                        }

                       // send multipart form data necesssary after file data...
                       dos.writeBytes(lineEnd);
                       dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                       // Responses from the server (code and message)

                       serverResponseCode = conn.getResponseCode();
                       String serverResponseMessage = conn.getResponseMessage();

                       Log.i("uploadFile", "HTTP Response is : "
                               + serverResponseMessage + ": " + serverResponseCode);
                       BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
                       StringBuilder sb = new StringBuilder();
                       String line = null;

                       while((line = in.readLine()) != null){
                           sb.append(line + "\n");
                           Log.d(">>>>>>>>>", sb.toString());
                       }


                       in.close();
                       json = sb.toString();
                       Log.d("json" , json);

                       try{
                            jobj = new JSONObject(json);
                            msg = jobj.getString("message");
                            paths.add(jobj.getString("path"));
                            Log.d("msg>>>>>>>>>>>>",msg);

                        }catch(JSONException e){
                            Log.e("JSON Parser", "Error parsing data " + e.toString());
                        }

                       if(serverResponseCode == 200){


                       }    

                       //close the streams //
                       fileInputStream.close();
                       dos.flush();
                       dos.close();

                  } catch (MalformedURLException ex) {


                      ex.printStackTrace();



                      Log.e("Upload file to server", "error: " + ex.getMessage(), ex);  
                  } catch (Exception e) {

                      e.printStackTrace();


                      Log.e("Upload file to server Exception", "Exception : "
                                                       + e.getMessage(), e);  
                  }



               } // End else block 
              return msg; 
             } 
        protected void onPostExecute(String file_url) {

            successcount++;
             if(pDialog != null && pDialog.isShowing()){
                 pDialog.dismiss();
                 }
        }


    }

my question is How can i compress the image? and also where to pass this compressed image in above function?

vish
  • 45
  • 1
  • 8
  • out of memory exception i guess...? – GvSharma Apr 15 '14 at 12:06
  • Your server may have a limitation on how large an upload can be. You can configure it to accept larger files. If you are using apache, I believe the default is 2mb. – KennyC Apr 15 '14 at 12:30

3 Answers3

2

You need to do this man:

1: Get Image and check size. For example: if fileSize<=1MB

2: ShrinkBitmap (So that large image won't cause memory issues. See ShrinkBitmap() below.

3: If you want to Encode to base64 or else then you can do it and compress to 100%. See Encodetobase64() below

4: Send to Server

public Bitmap ShrinkBitmap(String file, int width, int height)
{
    BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
    bmpFactoryOptions.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);

    int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight / (float) height);
    int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth / (float) width);

    if(heightRatio > 1 || widthRatio > 1)
    {
        if(heightRatio > widthRatio)
        {
            bmpFactoryOptions.inSampleSize = heightRatio;
        }
        else
        {
            bmpFactoryOptions.inSampleSize = widthRatio;
        }
    }

    bmpFactoryOptions.inJustDecodeBounds = false;
    bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
    return bitmap;
}  



    public String encodeTobase64(Bitmap image)
{
    String byteImage = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] b = baos.toByteArray();
    try
    {
        System.gc();
        byteImage = Base64.encodeToString(b, Base64.DEFAULT);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    catch (OutOfMemoryError e)
    {
        baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        b = baos.toByteArray();
        byteImage = Base64.encodeToString(b, Base64.DEFAULT);
        Log.e("Bitmap", "Out of memory error catched");
    }
    return byteImage;
}  

This encoding function is compressing bitmap also.

Goodluck!!

Noman
  • 4,049
  • 10
  • 38
  • 59
1

In my app too i face this problem.what i have done was, i uploaded the images and set that to imageview and i gave static height and width to be 300*300. and saved the bitmap in server.

bitmap = Bitmap.createScaledBitmap(bitmap,desiredImageWidth,desiredImageHeight,true);

sace this in server. here desiredImageWidth, desiredImageHeight are static values.

Noman
  • 4,049
  • 10
  • 38
  • 59
GvSharma
  • 2,632
  • 1
  • 24
  • 30
  • Ok...this is for scaling the image..but after scaling where to apply this bitmap in above function – vish Apr 15 '14 at 12:11
  • you wrote method uploadFile(String filepath,String remark,String dt, String hid,String pid, String form)...... where you are calling this method, there you have to pass the string path of image.. try this – GvSharma Apr 15 '14 at 12:23
  • you mean i need to pass this bitmap to filepath argument of function? – vish Apr 15 '14 at 12:26
  • 1
    you got string path first na.so convert it to bitmap and compress it. instead of sending string file path as first argument to that method change that first argument to Bitmap bitmap. or you need String file path only then again convert the compressed bitmap to String. hope this one could help you – GvSharma Apr 15 '14 at 12:30
0
  1. For compressing an image use this library that is on GitHub (reduce size):

    https://github.com/zetbaitsu/Compressor

  2. Encode to base64:


public String encodeBase64(Bitmap image){
    ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS);
    return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
}
  1. Send base64 String to server via volley request (Post or Get method):

    https://developer.android.com/training/volley/simple.html

Nikola
  • 109
  • 1
  • 3
  • 13