Send a Picture or Image to php Server - android

I need to know the BEST way to load a bitmap and send it via http as a string, because i want to store it in a database. So could you help me with any ideas, please?
Thanks in advance, Regards
I had something this:
public byte[] ConvertBitmaptoBits(Bitmap src)
{
try{
ByteArrayOutputStream os=new ByteArrayOutputStream();
src.compress( android.graphics.Bitmap.CompressFormat.PNG, 100, (OutputStream)os );
src.compress(Bitmap.CompressFormat.PNG, 100, os); //bm is the bitmap object
byte[] b = os.toByteArray();
return b;
}catch(Throwable e)
{
//Toast.makeText(this, "Error en ConvierteBitmapAString: " + e.getMessage(), 30);
Log.v("ConvierteBitmapACadena", "Error al Convertir la imagen a Cadena: " + e.getMessage());
return null;
}
}
In my SEND method i had something like this:
public void Send() //throws Exception
{
try
{
InputStreamBody isb=null;
StringBody sImageString=null;
Resources r = this.getResources();
Bitmap bmp = BitmapFactory.decodeResource(r, R.drawable.icon);
byte[] objImageBits = ConvertBitmaptoBits(bmp);
if(objImageBits !=null ){
isb = new InputStreamBody(new ByteArrayInputStream(objImageBits), "uploadedFile");
}
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(strPath);
SimpleDateFormat sdfDateTime = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String strCurDate = sdfDateTime.format(new Date(System.currentTimeMillis()));
StringBody sCurDate = new StringBody(strCurDate);
MultipartEntity multipartContent = new MultipartEntity();
if(objImageBits !=null)
{
multipartContent.addPart("uploadedFile", isb);
}
multipartContent.addPart("fechaequipo", sCurDate);
postRequest.setEntity(multipartContent);
HttpResponse response = httpClient.execute(postRequest);
response.getEntity().getContent().close();
}
catch (Throwable e)
{
Log.v("executeMultipartPost", "Error in executeMultipartPost: " + e.getMessage());
}
}
But it seems i am not getting the uploadedFile. This is my php script:
$file2 = (isset($_POST['uploadedFile'])) ? ( $_POST['uploadedFile'] ):('');
$fechaequipo = (isset($_POST['fechaequipo']) ) ? ( $_POST['fechaequipo'] ):('');
$fp = null;
$log_file = 'log.txt';
if (!$fp)
$fp = fopen($log_file, 'a') or exit("No se puede abrir: $log_file!");
fwrite($fp, "<INI LOG>" . date("d/m/Y") ."\n\r");
fwrite($fp, "Date : ". $fechaequipo . "\n\r");
fwrite($fp, "File2 : " . $file2 . "\n\r");
fwrite($fp, "<END LOG>" . date("d/m/Y") ."\n\r");
fclose($fp);
?>
Do I'm doing anything wrong? Thanks in advance!!!

A similar question (in a sense) is here.
You convert you image to base64, then send to a server however you like. The server can then decode the string to an image. (With PHP, that'd be base64-decode).
Bear in mind that base64 encoding increases the size of the data transferred by about 33%.

Related

Decoding error,image format unsupported Azure

I am running a flask server at the backend. I want to read the image from mobile app and send it to the server to detect faces.
This is the java code(client side) for sending image as bytes -
public class client {
public static void main(String [] args) throws Exception{
String url = "http://127.0.0.1:8080/facial";
// 2. create obj for the URL class
URL obj = new URL(url);
// 3. open connection on the url
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type","image/jpeg");
con.setDoInput(true);
con.setDoOutput(true);
try {
System.out.println("Reading image from disk. ");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.flush();
File file = new File("jpeg.jpg");
BufferedImage image1 = ImageIO.read(file);
ImageIO.write(image1, "jpg", baos);
baos.flush();
System.out.println(baos.size());
byte[] bytes = baos.toByteArray();
baos.close();
System.out.println("Sending image to server. ");
OutputStream out = con.getOutputStream();
DataOutputStream image = new DataOutputStream(out);
image.writeInt(bytes.length);
image.write(bytes, 0, bytes.length);
System.out.println("Image sent to server. ");
image.close();
// close the output stream
out.close();
}catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
// define object for the reply from the server
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
//Get response from server
int responseCode = con.getResponseCode();
System.out.println("Response Code : " + responseCode);
// read in the response from the server
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
System.out.println(inputLine);
}
// close the input stream
in.close();
}
}
This is my server code -
def get_facial(data):
face_api_url = 'https://southeastasia.api.cognitive.microsoft.com/face/v1.0/detect'
# Set image_url to the URL of an image that you want to analyze.
headers = {'Ocp-Apim-Subscription-Key': subscription_key,
"Content-Type":"application/octet-stream"
}
params = {
'returnFaceId': 'true',
'returnFaceLandmarks': 'false',
'returnFaceAttributes': 'age,gender,headPose,smile,facialHair,glasses,' +
'emotion,hair,makeup,occlusion,accessories,blur,exposure,noise'
}
response = requests.post(face_api_url, params=params, headers=headers, data=data)
faces = response.json()
res={}
import pdb; pdb.set_trace()
res["status"] = '200'
res["num"] = str(len(faces))
return res
#app.route('/facial',methods=['POST'])
def facial():
import pdb; pdb.set_trace()
data=bytes(request.get_data())
res={}
try:
res = get_facial(data)
except:
res['status'] = '404'
print(res)
return json.dumps(res)
After examining - I sent the same image from another python file and checked the size of the data. It was 102564 bytes and it works but
the same image read and sent from java code is 106208 bytes. I don't know where exactly the mistake is.
Any help is appreciated !!:-)
I found a quick fix to this problem -
Path path = Paths.get("jpeg.jpg");
byte[] fileContents = Files.readAllBytes(path);
image.write(fileContents, 0, fileContents.length);
I don't exactly know why reading from imageio fails. My guess is that its also reading the file headers of the jpg file.

Send picture with httpurlconnection

Hi I am making an app which sends picture to a server. The version with the Apache deprecated functions work, but I don't know why I can't get the updated solution to work. Anybody knows where is the error here?
Newest solution : it does not give errors in the logcat but when I go to the server nothing has been uploaded. At first I thought that the error was in how I passed the arguments, but I have tried several different solutions like using Uri.builder, methods which encoded the params using a HashMap and an stringBuilder, passing the string like this... and NOTHING worked. I need help this is really driving me crazy
#Override
protected Void doInBackground(Void... params) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
try {
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
}catch (IOException e){
}
HttpURLConnection connection;
try {
String urlSt = "http://phoenixcoding.tk/SavePicture.php";
URL url = new URL(urlSt);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
/*Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("name", name)
.appendQueryParameter("image", encodedImage);
String query = builder.build().getEncodedQuery();*/
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write("name=example&image=" + encodedImage);
writer.flush();
writer.close();
os.close();
connection.connect();
}catch (IOException e){
e.printStackTrace();
}
return null;
}
Former solution: it works nicely
#Override
protected Void doInBackground(Void... params) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
String encodedImage = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
try {
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
}catch (IOException e){
}ArrayList<NameValuePair> dataToSend = new ArrayList<NameValuePair>();
dataToSend.add(new BasicNameValuePair("name", name));
dataToSend.add(new BasicNameValuePair("image", encodedImage));
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://phoenixcoding.tk/SavePicture.php");
try{
post.setEntity(new UrlEncodedFormEntity(dataToSend));
client.execute(post);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
The SavePhoto.php file:
<?php
$name = $_POST["name"];
$image = $_POST["image"];
$decodedImage = base64_decode("$image");
file_put_contents("pictures/" . $name . ".JPG", $decodedImage);
?>
Try this in your php code:
if( isset($_POST["image"]) && !empty($_POST["image"])){
$profile_pic = '';
$data= $_POST['image'];
$data = str_replace('data:image/png;base64,', '', $data);
$data = str_replace(' ', '+', $data);
$binary=base64_decode($data);
header('Content-Type: bitmap; charset=utf-8');
// Images will be saved under 'www/pictures' folder
$new_name = $_POST['name'] . '.png';
$success =file_put_contents('pictures/'.$new_name,$binary);
$profile_pic = $new_name;
}
i guess this line is buggy :- $decodedImage = base64_decode("$image"); u must write like this instead $decodedImage = base64_decode($image);
to debug do this :-
<?php
file_put_contents("post.txt",print_r($_POST,true));
$name = $_POST["name"];
.....
?>
view that as :- http://phoenixcoding.tk/post.txt
( if the file is not saved then there is permission issue in that case make a directory "test" and give it permission 755 even if it does not work make that directory as 777 and then you url will be http://phoenixcoding.tk/test/post.txt )
What you will do is collect all incoming $_POST in file then you will know what post data is coming this will clarify where the error is , on android side or php side if post is okay then android code is okay and issue is in php code.
i hope it will help you fixing the issue...
thanks
Thanks all for your answers, I finally made it work. I have no idea why is this, but after adding an InputStream object after opening the connection, the pictures uploaded correctly. All I did was add these lines:
InputStream is = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder str = new StringBuilder();
String strLine;
while ((strLine = reader.readLine()) != null) {
str.append(strLine + "\n");
}
is.close();

Android RestFul API call for post method

I am having a doubt on how can I post a data where my REST end point URL is like below:
http://my.domain.com/Upload/{ID}/{IMAGE_CONTENT_AS_BYTE_ARRAY}
I need to send the the Image content as byte array string to this end point method. But Since the charater length can go beyond 2000 character length, I may not be able to send the the IMAGE if its huge since everything goes as part of URL string. How can I put the data of IMAGE_CONTENT_AS_BYTE_ARRAY .
Also I don't have any key for this so that I can put it in namevalue pair.Please suggest!
Try this code:
MultipartEntityBuilder multipartEntity;
String URL = "My server url";
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
bitmap.compress(CompressFormat.JPEG, 75, byteArrayOutputStream);
byte[] byteData = byteArrayOutputStream.toByteArray();
ByteArrayBody byteArrayBody = new ByteArrayBody(byteData, "image"); // second parameter is the name of the image )
// send the package
multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("image", byteArrayBody);
The best way to upload images or files is using multi part data format.
Here is a sample code for uploading image.
public static void postMultiPart(String url, File image)
{
final android.net.http.AndroidHttpClient client = android.net.http.AndroidHttpClient.newInstance("sample");
// enable redirects
HttpClientParams.setRedirecting(client.getParams(), true);
final String encoded_url = encodeURL(url);
final org.apache.http.client.methods.HttpPost post = new org.apache.http.client.methods.HttpPost(encoded_url);
MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
mpEntity.addPart("profile", new FileBody(image));
post.setEntity(mpEntity);
org.apache.http.HttpResponse response;
try {
response = client.execute(post);
final int statusCode = response.getStatusLine().getStatusCode();
if (!(statusCode == org.apache.http.HttpStatus.SC_OK || statusCode == org.apache.http.HttpStatus.SC_CREATED)) {
Log.i("Error:","Check....."+"Error " + statusCode + " while posting data to " + encoded_url + "\nreason phrase: " + response.getStatusLine().getReasonPhrase());
return;
}
Log.i("SUCCESS:","Check....."+Base64.encodeToString(md.digest(), Base64.DEFAULT));
} catch (IOException e) {
} finally {
client.close();
}
}

Sending multipart form data with image and text in android

I have code to send text and multiple image in one request to server, my case is, I loop through local db to get the data and multiple image so I can use addPart(key, textdata); for the text data and addPart(key, filename, inputstream, "application/octet-stream"); for the image data. But the problem is when I have more than one image in one request I only able to send one of them. Here are my complete code. The main problem happens on line 31 when I have more than one image it only send one of them. I will appreciate any help. Thank you.
The problem I think is might be here
reqEntity.addPart("myFile", yourImage);
In this your key(myFile) remains the same for all the images. so when your images are more than one, it keeps on overwriting the previous image. So I think, you should attach index with your key(starting from 0,1 and so on), something like this for example
reqEntity.addPart("myFile_"+i, yourImage);
And also send the image_count to server along with images,so that, it will get to know how many images you are actually sending and by having a simple for loop at the server end,they will be able to get all these images. hope this helps.
Try this way
String sResponse = "";
String url = "http://www.api.in/rpcs/uploadfiles/?";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
options1.inPreferredConfig = Bitmap.Config.ARGB_8888;
byte[] data1 = null,data2= null,data3= null,data4= null,data5= null;
if(PreferenceManager.getDefaultSharedPreferences(getBaseContext()).contains("endum_image_0"))
{ up_image1 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("endum_image_0", "");
bitmap = BitmapFactory.decodeFile(up_image1, options1);
bitmap.compress(CompressFormat.JPEG, 100, bos1);
data1 = bos1.toByteArray();
}
if(PreferenceManager.getDefaultSharedPreferences(getBaseContext()).contains("endum_image_1"))
{ up_image2 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("endum_image_1", "");
bitmap = BitmapFactory.decodeFile(up_image2, options1);
bitmap.compress(CompressFormat.JPEG, 100, bos2);
data2 = bos2.toByteArray();
}
if(PreferenceManager.getDefaultSharedPreferences(getBaseContext()).contains("endum_image_2"))
{ up_image3 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("endum_image_2", "");
bitmap = BitmapFactory.decodeFile(up_image3, options1);
bitmap.compress(CompressFormat.JPEG, 100, bos3);
data3 = bos3.toByteArray();
}
if(PreferenceManager.getDefaultSharedPreferences(getBaseContext()).contains("endum_image_3"))
{ up_image4 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("endum_image_3", "");
bitmap = BitmapFactory.decodeFile(up_image4, options1);
bitmap.compress(CompressFormat.JPEG, 100, bos4);
data4 = bos4.toByteArray();
}
if(PreferenceManager.getDefaultSharedPreferences(getBaseContext()).contains("endum_image_4"))
{ up_image5 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()).getString("endum_image_4", "");
bitmap = BitmapFactory.decodeFile(up_image5, options1);
bitmap.compress(CompressFormat.JPEG, 100, bos5);
data5 = bos5.toByteArray();
}
entity.addPart("post_id", new StringBody(post_id));
entity.addPart("user_id", new StringBody(user_id));
entity.addPart("cat_id", new StringBody(category));
if(data1!=null){
entity.addPart("files[]", new ByteArrayBody(data1,"image/jpeg", "u1.jpg"));
}
if(data2!=null){
entity.addPart("files[]", new ByteArrayBody(data2,"image/jpeg", "u2.jpg"));
}
if(data3!=null){
entity.addPart("files[]", new ByteArrayBody(data3,"image/jpeg", "u3.jpg"));
}
if(data4!=null){
entity.addPart("files[]", new ByteArrayBody(data4,"image/jpeg", "u4.jpg"));
}
if(data5!=null){
entity.addPart("files[]", new ByteArrayBody(data5,"image/jpeg", "u5.jpg"));
}
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null)
{
s = s.append(sResponse);
}
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
return s.toString();
}else
{
return "{\"status\":\"false\",\"message\":\"Some error occurred\"}";
}

Android Large File Upload as Byte Array to Restful WCF Service giving Bad Request

I am facing problem while trying to upload a zip file containing images converted into byte array to a restful wcf service from a json client using HTTPPost. The byte array is encoded into BASE64 enclosed into JSON object and sent using StringEntity with 2 more parameters. Around 6KB of file gets uploaded without any flaws but file more than 6KB are not send and I get a Bad Request - 400 status code. Following code is used to upload the file:
File file = new File(dir, "file.zip");
byte[] buf = new byte[10240000];
fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (int readNum; (readNum = fis.read(buf)) != -1;) {
bos.write(buf, 0, readNum);
Log.v("read : buf ", buf + " : " + readNum + " bytes");
}
byte[] bytes = bos.toByteArray();
imgData = Base64.encodeToString(bytes, Base64.DEFAULT);
JSONObject sendData=null;
Log.d("Image Data length", imgData.length()+"");
Log.d("Image data ", imgData);
try {
sendData= new JSONObject();
sendData.put("_binaryData", imgData);
sendData.put("_fileName", "fileName");
sendData.put("userid", userID);
int len = imgData.length();
int l=sendData.toString().length();
entity = new StringEntity(sendData.toString());
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Send request
int len = imgData.length();
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
request.setHeader("Connection", "Keep-Alive");
request.setParams(httpParameters);
DefaultHttpClient httpClient = new DefaultHttpClient();
request.setEntity(entity);
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
String str=response.getStatusLine().getReasonPhrase();
int i=response.getStatusLine().getStatusCode();
Log.v("ReasonPhrase :: StatusCode",str+" "+i);
int contentLength = (int) responseEntity.getContentLength();
char[] buffer = new char[(int) responseEntity
.getContentLength()];
InputStream stream = responseEntity.getContent();
Please help me in solving this.
If a message with <6k bytes does through, but messages with >6k don't, I'd take a look at the client and host limits for things like:
MaxBufferSize
MaxBufferPoolSize
MaxReceivedMessageSize
You don't say whether or not you have control over the host server settings, but you can increase and decrease the limits on items like those mentioned earlier. You can set them to Integer.Max if necessary, a size that would allow file uploads > 1 GB.

Categories

Resources