102

I want to know which is the best way to upload image to server without losing its quality.

I have searched on google found various methods of posting data. But I am not sure which one would be best to upload. I came across:

  1. Multipart Image Upload.
  2. Uploading images using byte array
  3. Uploading images using base64 encoded string.

I have tried Base64 encoding it leads me to OOM(Out of memory) if image is too high in resolution.

1
  • 8
    Multipart image loading is good, you can try that if needed i'll provide the code Commented Dec 2, 2013 at 7:07

5 Answers 5

95
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, 1); 

ABOVE CODE TO SELECT IMAGE FROM GALLERY

@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) if (resultCode == Activity.RESULT_OK) { Uri selectedImage = data.getData(); String filePath = getPath(selectedImage); String file_extn = filePath.substring(filePath.lastIndexOf(".") + 1); image_name_tv.setText(filePath); try { if (file_extn.equals("img") || file_extn.equals("jpg") || file_extn.equals("jpeg") || file_extn.equals("gif") || file_extn.equals("png")) { //FINE } else { //NOT IN REQUIRED FORMAT } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public String getPath(Uri uri) { String[] projection = {MediaColumns.DATA}; Cursor cursor = managedQuery(uri, projection, null, null, null); column_index = cursor .getColumnIndexOrThrow(MediaColumns.DATA); cursor.moveToFirst(); imagePath = cursor.getString(column_index); return cursor.getString(column_index); } 

NOW POST THE DATA USING MULTIPART FORM DATA

HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("LINK TO SERVER"); 

Multipart FORM DATA

MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE); if (filePath != null) { File file = new File(filePath); Log.d("EDIT USER PROFILE", "UPLOAD: file length = " + file.length()); Log.d("EDIT USER PROFILE", "UPLOAD: file exist = " + file.exists()); mpEntity.addPart("avatar", new FileBody(file, "application/octet")); } 

FINALLY POST DATA TO SERVER

httppost.setEntity(mpEntity); HttpResponse response = httpclient.execute(httppost); 
Sign up to request clarification or add additional context in comments.

5 Comments

@Manoj please mark the answer as correct if Nitin's solution has helped you.
@DwivediJi you can post your answer as well, people get benefit from it, No Offence.
@Iqbal As i can imagine you're running it on Android 6.0 or greater you need to comply with the new Android permission Model and ask user's permission to access read/write external storage Follow this for more : developer.android.com/training/permissions/index.html
What is the gradle of HTTPPOST ?
This needs some more background. For instance, what are the gradle commands, and what imports are needed for this to even compile?
19

Main activity class to take pick and upload

import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.provider.MediaStore; //import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import java.io.ByteArrayOutputStream; import java.util.ArrayList; public class MainActivity extends Activity { Button btpic, btnup; private Uri fileUri; String picturePath; Uri selectedImage; Bitmap photo; String ba1; public static String URL = "Paste your URL here"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btpic = (Button) findViewById(R.id.cpic); btpic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { clickpic(); } }); btnup = (Button) findViewById(R.id.up); btnup.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { upload(); } }); } private void upload() { // Image location URL Log.e("path", "----------------" + picturePath); // Image Bitmap bm = BitmapFactory.decodeFile(picturePath); ByteArrayOutputStream bao = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 90, bao); byte[] ba = bao.toByteArray(); //ba1 = Base64.encodeBytes(ba); Log.e("base64", "-----" + ba1); // Upload image to server new uploadToServer().execute(); } private void clickpic() { // Check Camera if (getApplicationContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_CAMERA)) { // Open default camera Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // start the image capture Intent startActivityForResult(intent, 100); } else { Toast.makeText(getApplication(), "Camera not supported", Toast.LENGTH_LONG).show(); } } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode == RESULT_OK) { selectedImage = data.getData(); photo = (Bitmap) data.getExtras().get("data"); // Cursor to get image uri to display String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); picturePath = cursor.getString(columnIndex); cursor.close(); Bitmap photo = (Bitmap) data.getExtras().get("data"); ImageView imageView = (ImageView) findViewById(R.id.Imageprev); imageView.setImageBitmap(photo); } } public class uploadToServer extends AsyncTask<Void, Void, String> { private ProgressDialog pd = new ProgressDialog(MainActivity.this); protected void onPreExecute() { super.onPreExecute(); pd.setMessage("Wait image uploading!"); pd.show(); } @Override protected String doInBackground(Void... params) { ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("base64", ba1)); nameValuePairs.add(new BasicNameValuePair("ImageName", System.currentTimeMillis() + ".jpg")); try { HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(URL); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = httpclient.execute(httppost); String st = EntityUtils.toString(response.getEntity()); Log.v("log_tag", "In the try Loop" + st); } catch (Exception e) { Log.v("log_tag", "Error in http connection " + e.toString()); } return "Success"; } protected void onPostExecute(String result) { super.onPostExecute(result); pd.hide(); pd.dismiss(); } } } 

php code to handle upload image and also create image from base64 encoded data

<?php error_reporting(E_ALL); if(isset($_POST['ImageName'])){ $imgname = $_POST['ImageName']; $imsrc = base64_decode($_POST['base64']); $fp = fopen($imgname, 'w'); fwrite($fp, $imsrc); if(fclose($fp)){ echo "Image uploaded"; }else{ echo "Error uploading image"; } } ?> 

1 Comment

Since most of this is deprecated I've been trying to update the code... it's very frustrating. :) I was able to replace "NameValuePair" with "Pair" and I'm using HttpUrlConnection instead of the apache stuff. But I get lost at the "post" part.
9

use below code it helps you....

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; options.inPurgeable = true; Bitmap bm = BitmapFactory.decodeFile("your path of image",options); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG,40,baos); // bitmap object byteImage_photo = baos.toByteArray(); //generate base64 string of image String encodedImage =Base64.encodeToString(byteImage_photo,Base64.DEFAULT); //send this encoded string to server 

Comments

6

Try this method for uploading Image file from camera

package com.example.imageupload; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.message.BasicHeader; public class MultipartEntity implements HttpEntity { private String boundary = null; ByteArrayOutputStream out = new ByteArrayOutputStream(); boolean isSetLast = false; boolean isSetFirst = false; public MultipartEntity() { this.boundary = System.currentTimeMillis() + ""; } public void writeFirstBoundaryIfNeeds() { if (!isSetFirst) { try { out.write(("--" + boundary + "\r\n").getBytes()); } catch (final IOException e) { } } isSetFirst = true; } public void writeLastBoundaryIfNeeds() { if (isSetLast) { return; } try { out.write(("\r\n--" + boundary + "--\r\n").getBytes()); } catch (final IOException e) { } isSetLast = true; } public void addPart(final String key, final String value) { writeFirstBoundaryIfNeeds(); try { out.write(("Content-Disposition: form-data; name=\"" + key + "\"\r\n") .getBytes()); out.write("Content-Type: text/plain; charset=UTF-8\r\n".getBytes()); out.write("Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes()); out.write(value.getBytes()); out.write(("\r\n--" + boundary + "\r\n").getBytes()); } catch (final IOException e) { } } public void addPart(final String key, final String fileName, final InputStream fin) { addPart(key, fileName, fin, "application/octet-stream"); } public void addPart(final String key, final String fileName, final InputStream fin, String type) { writeFirstBoundaryIfNeeds(); try { type = "Content-Type: " + type + "\r\n"; out.write(("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + fileName + "\"\r\n").getBytes()); out.write(type.getBytes()); out.write("Content-Transfer-Encoding: binary\r\n\r\n".getBytes()); final byte[] tmp = new byte[4096]; int l = 0; while ((l = fin.read(tmp)) != -1) { out.write(tmp, 0, l); } out.flush(); } catch (final IOException e) { } finally { try { fin.close(); } catch (final IOException e) { } } } public void addPart(final String key, final File value) { try { addPart(key, value.getName(), new FileInputStream(value)); } catch (final FileNotFoundException e) { } } public long getContentLength() { writeLastBoundaryIfNeeds(); return out.toByteArray().length; } public Header getContentType() { return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + boundary); } public boolean isChunked() { return false; } public boolean isRepeatable() { return false; } public boolean isStreaming() { return false; } public void writeTo(final OutputStream outstream) throws IOException { outstream.write(out.toByteArray()); } public Header getContentEncoding() { return null; } public void consumeContent() throws IOException, UnsupportedOperationException { if (isStreaming()) { throw new UnsupportedOperationException( "Streaming entity does not implement #consumeContent()"); } } public InputStream getContent() throws IOException, UnsupportedOperationException { return new ByteArrayInputStream(out.toByteArray()); } } 

Use of class for uploading

private void doFileUpload(File file_path) { Log.d("Uri", "Do file path" + file_path); try { HttpClient client = new DefaultHttpClient(); //use your server path of php file HttpPost post = new HttpPost(ServerUploadPath); Log.d("ServerPath", "Path" + ServerUploadPath); FileBody bin1 = new FileBody(file_path); Log.d("Enter", "Filebody complete " + bin1); MultipartEntity reqEntity = new MultipartEntity(); reqEntity.addPart("uploaded_file", bin1); reqEntity.addPart("email", new StringBody(useremail)); post.setEntity(reqEntity); Log.d("Enter", "Image send complete"); HttpResponse response = client.execute(post); resEntity = response.getEntity(); Log.d("Enter", "Get Response"); try { final String response_str = EntityUtils.toString(resEntity); if (resEntity != null) { Log.i("RESPONSE", response_str); JSONObject jobj = new JSONObject(response_str); result = jobj.getString("ResponseCode"); Log.e("Result", "...." + result); } } catch (Exception ex) { Log.e("Debug", "error: " + ex.getMessage(), ex); } } catch (Exception e) { Log.e("Upload Exception", ""); e.printStackTrace(); } } 

Service for uploading

 <?php $image_name = $_FILES["uploaded_file"]["name"]; $tmp_arr = explode(".",$image_name); $img_extn = end($tmp_arr); $new_image_name = 'image_'. uniqid() .'.'.$img_extn; $flag=0; if (file_exists("Images/".$new_image_name)) { $msg=$new_image_name . " already exists." header('Content-type: application/json'); echo json_encode(array("ResponseCode"=>"2","ResponseMsg"=>$msg)); }else{ move_uploaded_file($_FILES["uploaded_file"]["tmp_name"],"Images/". $new_image_name); $flag = 1; } if($flag == 1){ require 'db.php'; $static_url =$new_image_name; $conn=mysql_connect($db_host,$db_username,$db_password) or die("unable to connect localhost".mysql_error()); $db=mysql_select_db($db_database,$conn) or die("unable to select message_app"); $email = ""; if((isset($_REQUEST['email']))) { $email = $_REQUEST['email']; } $sql ="insert into alert(images) values('$static_url')"; $result=mysql_query($sql); if($result){ echo json_encode(array("ResponseCode"=>"1","ResponseMsg"=> "Insert data successfully.","Result"=>"True","ImageName"=>$static_url,"email"=>$email)); } else { echo json_encode(array("ResponseCode"=>"2","ResponseMsg"=> "Could not insert data.","Result"=>"False","email"=>$email)); } } else{ echo json_encode(array("ResponseCode"=>"2","ResponseMsg"=> "Erroe While Inserting Image.","Result"=>"False")); } ?> 

5 Comments

org.apache.http was deprecated in API version 23. Can you update this example to use HttpURLConnection?
@MustModify google useLibrary 'org.apache.http.legacy'
Why would you want to use a library marked 'legacy'? Isn't there a replacement?
When to use legacy? When you have just installed gradle on an old Celeron with 32 bit Ubuntu, and can only use an older version of the build-tools. And it works 100%. That's when :)
Where is the rest of the code? There are all kinds of variables referenced here that are not defined. What do they do? I can figure out some, but I don't understand this well enough to know what's essential and what's extraneous (if I did, I wouldn't be here!).
1
//Kotlin Version private fun setImageForUploading (imagePath:String):String{ val options = BitmapFactory.Options(); options.inSampleSize = 2 //options.inPurgeable = true //deprecated val bitmap = BitmapFactory.decodeFile(imagePath,options) val byteArrayOutPutStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.PNG,90,byteArrayOutPutStream) // bitmap object val byteImagePhoto = byteArrayOutPutStream.toByteArray() //generate base64 string of image val encodedImage = Base64.encodeToString(byteImagePhoto,Base64.DEFAULT) return encodedImage } 

1 Comment

This is...how shall we say...incomplete? Yes, very incomplete. Where's the rest of the code?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.