Android - Resize & crop picture before sending without saving it - android

Please excuse my bad English, I'm French !
In my Android App, I have to resize and crop a picture from the gallery before sending it to a server WITHOUT saving it.
Here my code to send to the server :
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
String pathToOurFile = imagePath;
String urlServer = "http://ip/serverApp/upload/transfert.php";
Log.e("UploadImage", urlServer);
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
try
{
File file = new File(imagePath);
FileInputStream fileInputStream = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
fileInputStream.read(bytes);
fileInputStream.close();
URL url = new URL(urlServer);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
connection.setDoOutput(true);
outputStream = new DataOutputStream( connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile +"\"" + lineEnd);
outputStream.writeBytes(lineEnd);
int bufferLength = 1024;
for (int i = 0; i < bytes.length; i += bufferLength) {
int progress = (int)((i / (float) bytes.length) * 100);
publishProgress(progress);
if (bytes.length - i >= bufferLength) {
outputStream.write(bytes, i, bufferLength);
} else {
outputStream.write(bytes, i, bytes.length - i);
}
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
outputStream.close();
outputStream.flush();
InputStream inputStream = connection.getInputStream();
// read the response
inputStream.close();
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
Log.w("Upload image", "Response -> Code:"+serverResponseCode+" Message:"+serverResponseMessage);
return serverResponseCode;
}
catch (Exception ex)
{
ex.printStackTrace();
}
Now I need to code to resize and crop the picture in order to have image of a size of 350px/350px.
Do you know how I could do that ?
Thanks a lot.

OK !!!!
For the correct way follow this this code !
BUT : becarful, it's an example ! -> YOU SHOULDN'T DO A INTERNET REQUEST IN THE MAIN THREAD
for execute this code, the function exec(); should to be put into a "doInBackground()" of an asyncTask<Object, Object, Object>();
the startActivityForResult() and the override of onActivityResult() should to be into an activity class
tell me if it's correct !!!!
private int ACTIVITY_ID_PICK_PHOTO = 42;
private int maxWidth = 350;
private int maxHeight = 350;
private String url = "http://ip/serverApp/upload/transfert.php"
//Call the activity for select photo into the gallery
private void SelectPhoto(){
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, ACTIVITY_ID_PICK_PHOTO);
}
// check the return of the result
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//check th id of the result
if (requestCode == ACTIVITY_ID_PICK_PHOTO)
selectPhotoControl(data);
}
//Working data
private void selectPhotoControl(Intent data) {
//check if any photo is selected
if (data == null)
return;
//get the uri of the picture selected
Uri photoUri = data.getData();
if (photoUri != null) {
//decode the Uri
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(photoUri,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
//get the uri of the image
String filePath = cursor.getString(columnIndex);
cursor.close();
//get the image in the bitmap and resize the image
Bitmap bp = resize(filePath);
if (bp != null)
postImage(bp, filePath);
}
}
public static HttpResponse postImage(Bitmap bp, String uristr) throws ClientProtocolException, IOException {
//initialization of the postrequest
HttpPost httpPost = new HttpPost(url);
//create the multipart entitiy (if you want send another content)
MultipartEntity entity = new MultipartEntity(
//the boundary for separate the informations
HttpMultipartMode.BROWSER_COMPATIBLE, "------CustomBoundary", null);
if (bp != null) {
//create the bytes array for send the image
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//if you want to compress the image -> write the result into bos
bp.compress(CompressFormat.JPEG, 100, bos);
//get the filename of the image
String filename = uristr.substring(uristr.lastIndexOf("/") + 1,
uristr.length());
//put the picture into the body of this part
FormBodyPart fbp = new FormBodyPart("photo", new ByteArrayBody(
bos.toByteArray(), "image/jpeg", filename));
//add the part to the entity
entity.addPart(fbp);
}
//set the entity into the request
httpPost.setEntity(entity);
//execute the request
return exec(httpPost);
}
protected synchronized static HttpResponse exec(HttpRequestBase base) throws ClientProtocolException, IOException{
if (base != null)
//Execute the request
return mHttpClient.execute(base);
else
return null;
}
private Bitmap resize(String path){
// create the options
BitmapFactory.Options opts = new BitmapFactory.Options();
//just decode the file
opts.inJustDecodeBounds = true;
Bitmap bp = BitmapFactory.decodeFile(path, opts);
//get the original size
int orignalHeight = opts.outHeight;
int orignalWidth = opts.outWidth;
//initialization of the scale
int resizeScale = 1;
//get the good scale
if ( orignalWidth > maxWidth || orignalHeight > maxHeight ) {
final int heightRatio = Math.round((float) orignalHeight / (float) maxHeight);
final int widthRatio = Math.round((float) orignalWidth / (float) maxWidth);
resizeScale = heightRatio < widthRatio ? heightRatio : widthRatio;
}
//put the scale instruction (1 -> scale to (1/1); 8-> scale to 1/8)
opts.inSampleSize = resizeScale;
opts.inJustDecodeBounds = false;
//get the futur size of the bitmap
int bmSize = (orignalWidth / resizeScale) * (orignalHeight / resizeScale) * 4;
//check if it's possible to store into the vm java the picture
if ( Runtime.getRuntime().freeMemory() > bmSize ) {
//decode the file
bp = BitmapFactory.decodeFile(path, opts);
} else
return null;
return bp;
}

This answer [is based on another answer][1], but I had some problems with that code, so I post the edited and working code.
I did it like this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.outWidth = 50; //pixels
options.outHeight = 50; //pixels
InputStream in = context.getContentResolver().openInputStream(data.getData()); // here, you need to get your context.
Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] bitmapdata = baos.toByteArray();
Notice that, data is the returned data from the Intent you use to get the file. If you already have the file path, just use that...
And now, when you are creating the HTTP Entity, add:
FormBodyPart fbp = new FormBodyPart("image", new ByteArrayBody(baos.toByteArray(), "image/jpeg", "image"));
entity.addPart(fbp);
Also, notice that you need a MultipartEntity to upload files.

Related

unable to post base64 converted image to rest service

I've written a code that selects image from gallery and convert it into a BASE64 string. as the selected images was too large the string is too big to be posted.
I have compressed the image so that the length of the string could be reduced. but still the length of the string is still large.
The code that i used is as follows,
This function sets the selected image in an imageView and
if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
sPicturePath = cursor.getString(columnIndex);
cursor.close();
imageView = (ImageView) findViewById(R.id.imageView);
Bitmap bm = ShrinkBitmap(sPicturePath, 300, 300);
imageView.setImageBitmap(bm);
/**
* Compute size of the image selected image
*/
File file = new File(sPicturePath);
if (file.exists()) {
double bytes = file.length();
double kilobytes = (bytes / 1024);
double megabytes = (kilobytes / 1024);
System.out.println("megabytes : " + megabytes);
Log.d("size", String.valueOf(megabytes));
}
imageView.setImageBitmap(BitmapFactory.decodeFile(sPicturePath));
Bitmap bm1 = BitmapFactory.decodeFile(sPicturePath);
//CropImage();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm1.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object
byte[] byteArrayImage = baos.toByteArray();
encodedString = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
//Toast.makeText(getApplicationContext(), encodedString, Toast.LENGTH_SHORT).show();
String length = String.valueOf(encodedString.length());
//Toast.makeText(getApplicationContext(),lenght,Toast.LENGTH_SHORT).show();
Log.d("encodedString", encodedString);
Log.d("length", length);
ShrinkBitmap.java
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;
}
What i want to achieve is to select an image from gallery convert it into a BASE64 string and post it through a REST service.
A GET request has URL length restrictions. You need to send the file using MultipartEntity using HttpURLConnection. You need to create a post request.
If your filename is image.jpg.
Bitmap bitmap = ...;
String filename = "image.jpg";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
ContentBody contentPart = new ByteArrayBody(bos.toByteArray(), filename);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("picture", contentPart);
String response = multipost("http://server.com", reqEntity);
And this is the multipost function.
private static String multipost(String urlString, MultipartEntity reqEntity) {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
conn.addRequestProperty(reqEntity.getContentType().getName(), reqEntity.getContentType().getValue());
OutputStream os = conn.getOutputStream();
reqEntity.writeTo(conn.getOutputStream());
os.close();
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return readStream(conn.getInputStream());
}
} catch (Exception e) {
Log.e(TAG, "multipart post error " + e + "(" + urlString + ")");
}
return null;
}
private static String readStream(InputStream in) {
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
builder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return builder.toString();
}
More info at this SO thread.

How to resolve OutOfMemoryError on Bitmap in Android?

I want to set an image in ImageView, I am retrieving the image path in my first activity and I am passing it via Intent as a String to second activity. In the second activity I set the path to an ImageView. It's working properly, and I need to upload that picture to a server. So I decoded the path to a bitmap. It throws an OutOfMemoryError. How to resolve this issue?
And when I use front camera, there is no issues. Image is uploaded successfully. The problem is with the images taken by front camera of the device. What is the solution for this problem? Can anyone help?
Here is the code to convert the image path to a string and passing it via Intent:
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED, MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED, null, "date_added ASC");
if(cursor != null && cursor.moveToFirst())
{
do {
Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
photoPath = uri.toString();
}while(cursor.moveToNext());
cursor.close();
try {
Intent intent = new Intent(MainActivity.this, ImageUploadActivity.class);
intent.putExtra("ImagePath", photoPath);
MainActivity.this.startActivity(intent);
}
catch (Exception e)
{
Toast.makeText(MainActivity.this, "Method invoked"+photoPath, Toast.LENGTH_SHORT).show();
}
}
Receiving Intent in Second Activity:
Intent camIntent = getIntent();
camPicPath = camIntent.getExtras().getString("ImagePath");
imageView = (ImageView) findViewById(R.id.imgView);
imageView.setImageBitmap(BitmapFactory.decodeFile(camPicPath));
Toast.makeText(getApplicationContext(), "PATHe"+camPicPath, Toast.LENGTH_SHORT).show();
bitmap = (BitmapFactory.decodeFile(camPicPath));
Method to Upload the file:
class ImageUploadTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... unsued) {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost("http://11.10.11.15/test/upload.php");
MultipartEntity entity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
byte[] data = bos.toByteArray();
/* entity.addPart("uploaded_file", new ByteArrayBody(data,
"myImage.jpg"));*/
// String newFilename= filename.concat("file");
// newFilename=filename+newFilename;
entity.addPart("uploaded_file", new ByteArrayBody(data,
filename));
// Log.e(TAG, "Method invoked");
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost,
localContext);
BufferedReader reader = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
String aux = "";
while ((aux = reader.readLine()) != null) {
builder.append(aux);
}
String sResponse = builder.toString();
return sResponse;
} catch (Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getApplicationContext(), "Exception Message 1", Toast.LENGTH_LONG).show();
Log.e(e.getClass().getName(), e.getMessage(), e);
return null;
}
Use the following method:
Bitmap bm = ShrinkBitmap(imagefile, 300, 300);
image.setImageBitmap(bm);
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;
}
Or use inSampleSize when setting the image bitmap like this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
imageView.setImageBitmap(BitmapFactory.decodeFile(path, options));
you can add below property to application tag of manifiest file for high memory.
android:largeHeap="true"

Android send image to webserver

I have this task to send a picture i take with my app to a webserver. this is my camera activity where i would like to send the image in the onActivityResult method. I have trouble finding up to date solutions to this as all i can find seems to be using MultipartEntity which is now deprecated.
package com.ndjk;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ImageView;
public class CameraActivity extends Activity {
private static final int CAMERA_REQUEST = 1888;
public ImageView imageView;
public static final String URI_PATH = "Uri";
Uri imageUri = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frontpage);
imageView = (ImageView) findViewById(R.id.pictureImageView);
open();
}
public void open() {
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Bitmap bp = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(bp);
Intent frontPageIntent = new Intent(this, FrontPageActivity.class);
imageUri = data.getData();
frontPageIntent.putExtra(URI_PATH, imageUri.toString());
frontPageIntent.putExtra("MapPhoto", bp);
startActivity(frontPageIntent);
}
}
As an alternative, I would highly recommend using Retrofit a REST library from Square. Retrofit
You would create a Java interface like this:
#Multipart
#POST("/webservice/{userid}/avatar.json")
Object uploadImage(
#Header("Rest-User-Token") String token,
#Path("userid") String userId,
#Part("FileData") TypedFile pictureFile
);
Then it is just a case of converting the Intent data to a File object, and than creating a TypedFile as follows:
TypedFile in = new TypedFile("image/jpeg", imageFile);
I think the answer is here:
https://stackoverflow.com/a/19196621/1652236
You should use MultipartEntityBuilder as an alternative
Edit - 1
You can open camera with this code:
private static final int RESULT_TAKE_PHOTO = 1;
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, RESULT_TAKE_PHOTO);
Your onActivityResult must be like this :
if (resultCode == RESULT_OK) {
File file = null;
String filePath = null;
try {
Uri selectedImage = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
filePath = cursor.getString(columnIndex);
cursor.close();
rotateDegree = getCameraPhotoOrientation(getApplicationContext(), selectedImage, picturePath);
bmp = BitmapFactory.decodeFile(picturePath);
bmp = rotateImage(bmp, rotateDegree);
file = new File(filePath);
FileOutputStream fOut = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 70, fOut);
fOut.flush();
fOut.close();
resultCode=0;
} catch (Exception e) {
e.printStackTrace();
}
}
So if take the picture You can use this AsyncTask for sending. You can show a progress bar while sending file to server. It's working for me.
public class SendFile extends AsyncTask<String, Integer, Integer> {
private Context conT;
private ProgressDialog dialog;
private String SendUrl = "";
private String SendFile = "";
private String Parameters = "";
private String result;
public File file;
SendFile(Context activity, String url, String filePath, String values) {
conT = activity;
dialog = new ProgressDialog(conT);
SendUrl = url;
SendFile = filePath;
Parameters = Values;
}
#Override
protected void onPreExecute() {
file = new File(SendFile);
dialog.setMessage("Please Wait..");
dialog.setCancelable(false);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax((int) file.length());
dialog.show();
}
#Override
protected Integer doInBackground(String... params) {
HttpURLConnection connection = null;
DataOutputStream outputStream = null;
InputStream inputStream = null;
String twoHyphens = "--";
String boundary = "*****"
+ Long.toString(System.currentTimeMillis()) + "*****";
String lineEnd = "\r\n";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 512;
String[] q = SendFile.split("/");
int idx = q.length - 1;
try {
FileInputStream fileInputStream = new FileInputStream(file);
URL url = new URL(SendUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("User-Agent",
"Android Multipart HTTP Client 1.0");
connection.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
outputStream = new DataOutputStream(
connection.getOutputStream());
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream
.writeBytes("Content-Disposition: form-data; name=dosya; filename=\""
+ q[idx] + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: image/jpg" + lineEnd);
outputStream.writeBytes("Content-Transfer-Encoding: binary"
+ lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
int boyut = 0;
while (bytesRead > 0) {
boyut += bytesRead;
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
dialog.setProgress(boyut);
}
outputStream.writeBytes(lineEnd);
String[] posts = Bilgiler.split("&");
int max = posts.length;
for (int i = 0; i < max; i++) {
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
String[] kv = posts[i].split("=");
outputStream
.writeBytes("Content-Disposition: form-data; name=\""
+ kv[0] + "\"" + lineEnd);
outputStream.writeBytes("Content-Type: text/plain"
+ lineEnd);
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(kv[1]);
outputStream.writeBytes(lineEnd);
}
outputStream.writeBytes(twoHyphens + boundary + twoHyphens
+ lineEnd);
inputStream = connection.getInputStream();
result = this.convertStreamToString(inputStream);
Log.v("TAG","result:"+result);
fileInputStream.close();
inputStream.close();
outputStream.flush();
outputStream.close();
} catch (Exception e) {
}
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
dialog.setProgress(progress[0]);
}
#Override
protected void onPostExecute(Integer result1) {
dialog.dismiss();
};
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
and if you are sending to PHP server, this code will help you.
<?php
$file_path = "test/";
$username= $_POST["username"];
$password= $_POST["password"];
$file_path = $file_path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $file_path)) {
echo "success";
} else{
echo "fail";
}
?>
Edit - 2:
you can call this AsyncTask like :
String FormData = "username=" + Session.getUsername()
+ "&password=" + Session.getPassword() ;
SendFile SendIt= new SendFile(this, upLoadServerUri, filePath,FormData);
SendIt.execute();

how to capture images and post using json in android

I have two url, one for post captured image name and second for store image on that location. Now i finished process of open camera. When i take photo then image is stored on DCIM/CAMARA on device phone memory directory. But image is not post and store on two different url. What can i do for that?
Code for Open Camara
btn_camera = (Button)findViewById(R.id.btn_camera);
btn_camera.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, RESULT_LOAD_IMAGE);
// post(Image_URL, null);
}
});
> Code for Post data on url
try{
ArrayList<NameValuePair> mNameValuePair = new ArrayList<NameValuePair>();
mNameValuePair.add(new BasicNameValuePair("lid", lotids));
mNameValuePair.add(new BasicNameValuePair("aid", attandant_id));
mNameValuePair.add(new BasicNameValuePair("vnum", vehicle_number));
mNameValuePair.add(new BasicNameValuePair("imag", "xyz"));
Log.i("NameValuePair","" + mNameValuePair);
result = mCommonClass.PostConnection(Issue_Summons_Url, mNameValuePair);
Log.i("result for log",""+ result);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
Log.e("FastPark App","Nothing to be display");
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// get image from camera
case REQUEST_CODE_CAMERA_IMAGE:
if (resultCode == Activity.RESULT_OK) {
// Uri cameraImageUri = data.getData();
Log.e("", "camera uri= " + Uri.fromFile(getFile()));
String path=getFile().getAbsolutePath();
prepareTouploadImage(path);
}
break;
default;
break;
}
use this...in your main activity...u can get path from image
you can find the uri of the file from the camera intent and convert it to a binary data and upload it to the web service
How to upload a image to server using HttpPost in android? ,or if you want to store it in a different location other than in DCIM/CAMERA you can refer this webpage http://developer.android.com/training/camera/photobasics.html
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// get image from camera
case REQUEST_CODE_CAMERA_IMAGE:
if (resultCode == Activity.RESULT_OK) {
// Uri cameraImageUri = data.getData();
Log.e("", "camera uri= " + Uri.fromFile(getFile()));
String path=getFile().getAbsolutePath();
prepareTouploadImage(path);
}
break;
default;
break;
this path return your camera image path..
and this path will be posted in json.
/**
* encodes image to string using Base64
*
* #return
*/
private String prepareTouploadImage(String profileImagePath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(profileImagePath, options);
bitmap=Bitmap.createScaledBitmap(bitmap, 50, 50, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 50, baos);
bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
byte[] byteArray = baos.toByteArray();
String imageString = com.eg_lifestyle.utils.Base64
.encodeBytes(byteArray);
bitmap = null;
System.gc();
Runtime.getRuntime().gc();
return imageString;
}
this above method returns image converted to binary and return string
private void doFileUpload(){
HttpURLConnection conn = null;
DataOutputStream dos = null;
DataInputStream inStream = null;
String exsistingFileName = "/sdcard/six.3gp";
// Is this the place are you doing something wrong.
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1*1024*1024;
String urlString = "http://192.168.1.5/upload.php";
try
{
Log.e("MediaPlayer","Inside second Method");
FileInputStream fileInputStream = new FileInputStream(new File(exsistingFileName) );
URL url = new URL(urlString);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
// Allow Outputs
conn.setDoOutput(true);
// Don't use a cached copy.
conn.setUseCaches(false);
// Use a post method.
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
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=\"uploadedfile\";filename=\"" + exsistingFileName +"\"" + lineEnd);
dos.writeBytes(lineEnd);
Log.e("MediaPlayer","Headers are written");
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
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);
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
tv.append(inputLine);
// close streams
Log.e("MediaPlayer","File is written");
fileInputStream.close();
dos.flush();
dos.close();
}
catch (MalformedURLException ex)
{
Log.e("MediaPlayer", "error: " + ex.getMessage(), ex);
}
catch (IOException ioe)
{
Log.e("MediaPlayer", "error: " + ioe.getMessage(), ioe);
}
//------------------ read the SERVER RESPONSE
try {
inStream = new DataInputStream ( conn.getInputStream() );
String str;
while (( str = inStream.readLine()) != null)
{
Log.e("MediaPlayer","Server Response"+str);
}
/*while((str = inStream.readLine()) !=null ){
}*/
inStream.close();
}
catch (IOException ioex){
Log.e("MediaPlayer", "error: " + ioex.getMessage(), ioex);
}
use this function....i hope its useful to you to store images in specific folder on server

Compress camera image before upload

I am using this code (from www.internetria.com) to take a photo and upload to a server:
onCreate:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri output = Uri.fromFile(new File(foto));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, TAKE_PICTURE);
onActivityResult:
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setImageBitmap(BitmapFactory.decodeFile(foto));
File file = new File(foto);
if (file.exists()) {
UploaderFoto nuevaTarea = new UploaderFoto();
nuevaTarea.execute(foto);
}
else
Toast.makeText(getApplicationContext(), "No se ha realizado la foto", Toast.LENGTH_SHORT).show();
UploaderFoto:
ProgressDialog pDialog;
String miFoto = "";
#Override
protected Void doInBackground(String... params) {
miFoto = params[0];
try {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost("http://servidor.com/up.php");
File file = new File(miFoto);
MultipartEntity mpEntity = new MultipartEntity();
ContentBody foto = new FileBody(file, "image/jpeg");
mpEntity.addPart("fotoUp", foto);
httppost.setEntity(mpEntity);
httpclient.execute(httppost);
httpclient.getConnectionManager().shutdown();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
And I want to compress the image, because the size is too big.
I don't know how to add bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos); to my app
Take a look over here: ByteArrayOutputStream to a FileBody
Something along these lines should work:
replace
File file = new File(miFoto);
ContentBody foto = new FileBody(file, "image/jpeg");
with
Bitmap bmp = BitmapFactory.decodeFile(miFoto)
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
InputStream in = new ByteArrayInputStream(bos.toByteArray());
ContentBody foto = new InputStreamBody(in, "image/jpeg", "filename");
If file size is still an issue you may want to scale the picture in addition to compressing it.
Convert image to Google WebP format it will save you lots of bytes see the following two articles you can also convert webP into JPG/PNG/GIF whatever you want on server side.
Java Wrapper of Google WebP API
How to check out Google WebP library and use it in Android as native library
First, you need to get pixels from Bitmap.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
byte[] pixels = buffer.array();
Then, you can get WebP byte array.
int stride = bytes / height;
int quality = 100;
byte[] encoded = libwebp.WebPEncodeRGBA(pixels, width, height, stride, quality);
Test.png (Size: 106KB)
Test.webp(Size: 48KB)
Using okhttp I upload like this:
MediaType MEDIA_TYPE_PNG
= MediaType.parse("image/jpeg");
//Compress Image
Bitmap bmp = BitmapFactory.decodeFile(fileToUpload.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 70, bos);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("photo", fileToUpload.getName(), RequestBody.create(MEDIA_TYPE_PNG, bos.toByteArray()))
.build();
request = new Request.Builder()
.url(urlToUploadTo)
.post(requestBody)
.build();
try {
response = client.newCall(request).execute();
if (response != null) {
if (response.isSuccessful()) {
responseResult = response.body().string();
}
}
} catch (IOException e) {
e.printStackTrace();
}
Have a look at the compressImage() method:
public class MainActivity extends Activity {
private Uri fileUri;
private ImageView img_forCompress;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int CAMERA_REQUEST = 1888;
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final String IMAGE_DIRECTORY_NAME = "Ibook";
static File mediaFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img_forCompress = (ImageView) findViewById(R.id.img_forCompress);
img_forCompress.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent,
CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
});
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
Log.e("path", "media file:-" + mediaFile);
return mediaFile;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.e("path", "" + mediaFile.toString());
String filename = mediaFile.toString();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filename, options);
compressImage(bitmap);
}
private void compressImage(Bitmap photo) {
// TODO Auto-generated method stub
int imageWidth = photo.getWidth();
int imageHeight = photo.getHeight();
long length = mediaFile.length();
int newHeight = 0;
int newWidth = 0;
Toast.makeText(MainActivity.this, "oldwidth="+imageWidth+",oldHeight="+imageHeight,Toast.LENGTH_LONG).show();
Log.e("Old Image gheight and width---------", imageWidth + "-------"
+ imageHeight + " and Size is -- " + length);
if (imageHeight > 1500 || imageWidth > 1500) {
if (imageHeight > imageWidth) {
Log.e("height is more", "true");
newHeight = 1200;
newWidth = (newHeight * imageWidth / imageHeight);
}
if (imageWidth > imageHeight) {
Log.e("width is more", "true");
newWidth = 1200;
newHeight = (newWidth * imageHeight / imageWidth);
}
}
Toast.makeText(MainActivity.this, "newwidth="+newWidth+",newHeight="+newHeight,Toast.LENGTH_LONG).show();
Log.e("new Image gheight and width---------", newHeight + "-------"

Categories

Resources