Download Compressed Image
I am new to android. I have created one application to upload an image to a server. It works great for small images, but for large images (> 1MB) it doesn't. Here is my function to load the 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 do I compress the image? and also where to pass this compressed image in the function above?
source to share
You need to make this person:
1: get a picture and check the size. For example: if fileSize <= 1MB
2: ShrinkBitmap (so a large image doesn't cause memory problems. See ShrinkBitmap () below.
3: If you want to base64 encode, otherwise you can do that 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 also compresses the bitmap.
Good luck!!
source to share
In my application too, I am facing this problem. What I did was I downloaded the images and set them to view images and I gave a static height and width 300 * 300. And saved the bitmap to the server.
bitmap = Bitmap.createScaledBitmap (bitmap, desiredImageWidth, desiredImageHeight, true);
sace it on the server. here wishImageWidth, wishImageHeight are static values.
source to share
-
To compress the image, use this library from GitHub (reduce size):
-
Base64 encode:
public String encodeBase64(Bitmap image){
ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOS);
return Base64.encodeToString(byteArrayOS.toByteArray(), Base64.DEFAULT);
}
-
Send base64 String to server via volleyball request (Post or Get method):
source to share