3

I am trying to send an Image from my android device over to an IIS server which is hosting a C#.NET based web handler.

The root problem I am facing now is how do I send it in to the server?
I have converted the image into base64 format but the part in which I have to send it in the HTTP's POST object is where I am facing a dilema.

                HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
                File data2send = new File(image_str);
                FileEntity fEntity = new FileEntity(data2send, "binary/octet-stream");
                httppost.setEntity(fEntity);


                //httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);

In the above snippet^ The line where I send my base64 string image_str cannot be of File type which is obvious.

So, I need something to convert this base64 string in-order to send it over to the server or better if someone can help me out here thoroughly :D

I tried the namevalue pairs way..it din't worked.

The Image I am sending is of ~3KB.

My full activity code:

public class MainActivity extends Activity {

    InputStream inputStream;


    private class GetRouteInfo extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();



        }

        @Override
        protected Void doInBackground(Void... params)
        {

       try 
       {
           Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img1);           
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); //compress to which format you want.
            byte [] byte_arr = stream.toByteArray();
            String image_str = Base64.encodeBytes(byte_arr);
            ArrayList<NameValuePair> nameValuePairs = new  ArrayList<NameValuePair>();

            System.out.println("image_str: "+image_str);

            nameValuePairs.add(new BasicNameValuePair("image",image_str));

            try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
                //post.addHeader("zipFileName", zipFileName);
                //httppost.addHeader("image",image_str);

                File data2send = new File();

                //File data2send = new File(image_str);
                FileEntity fEntity = new FileEntity(data2send, "binary/octet-stream");
                httppost.setEntity(fEntity);


                //httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                String the_string_response = convertResponseToString(response);
                //Toast.makeText(MainActivity.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
                System.out.println("Response " + the_string_response);

            }catch(Exception e){
                  //Toast.makeText(MainActivity.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
                System.out.println("ERROR " + e.getMessage());
                  System.out.println("Error in http connection "+e.toString());
            }

        }
       catch (Exception e) {
                Log.i("SvcMgr", "Service Execution Failed!", e);

            }

            finally {

                Log.i("SvcMgr", "Service Execution Completed...");

            }

            return null;
        }

        @Override
        protected void onCancelled() {
            Log.i("SvcMgr", "Service Execution Cancelled");
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            Log.i("SvcMgr", "Service Execution cycle completed");

        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.img1);           
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream); //compress to which format you want.
        byte [] byte_arr = stream.toByteArray();
        String image_str = Base64.encodeBytes(byte_arr);
        ArrayList<NameValuePair> nameValuePairs = new  ArrayList<NameValuePair>();

        nameValuePairs.add(new BasicNameValuePair("image",image_str));

        try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://192.168.1.248/imgup/Default.aspx");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            String the_string_response = convertResponseToString(response);
            Toast.makeText(MainActivity.this, "Response " + the_string_response, Toast.LENGTH_LONG).show();
        }catch(Exception e){
              Toast.makeText(MainActivity.this, "ERROR " + e.getMessage(), Toast.LENGTH_LONG).show();
              System.out.println("Error in http connection "+e.toString());
        }*/

        try {
            new GetRouteInfo().execute().get();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

     public String convertResponseToString(HttpResponse response) throws IllegalStateException, IOException{

         String res = "";
         StringBuffer buffer = new StringBuffer();
         inputStream = response.getEntity().getContent();
         int contentLength = (int) response.getEntity().getContentLength(); //getting content length…..
         System.out.println("contentLength : " + contentLength);
         //Toast.makeText(MainActivity.this, "contentLength : " + contentLength, Toast.LENGTH_LONG).show();
         if (contentLength < 0){
         }
         else{
                byte[] data = new byte[512];
                int len = 0;
                try
                {
                    while (-1 != (len = inputStream.read(data)) )
                    {
                        buffer.append(new String(data, 0, len)); //converting to string and appending  to stringbuffer…..
                    }
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                try
                {
                    inputStream.close(); // closing the stream…..
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                res = buffer.toString();     // converting stringbuffer to string…..

                System.out.println("Result : " + res);
                //Toast.makeText(MainActivity.this, "Result : " + res, Toast.LENGTH_LONG).show();
                //System.out.println("Response => " +  EntityUtils.toString(response.getEntity()));
         }
         return res;
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        //getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

Server Side code (in C#.net):

protected void Page_Load(object sender, EventArgs e)
    {

        if (System.IO.Directory.Exists(Server.MapPath("~/Data")))
        {
        }
        else
        {
            System.IO.Directory.CreateDirectory(Server.MapPath("~/Data"));

        }

    if(Request.InputStream.Length !=0 && Request.InputStream.Length < 32768) {
        //Request.ContentType = "binary/octet-stream";
        Request.ContentType = "text/plain";

        Stream myStream = Request.InputStream;

        string fName = Request.Params["image"];

        byte[] imageBytes = Convert.FromBase64String(myStream.ToString());
        MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);

        // Convert byte[] to Image
        ms.Write(imageBytes, 0, imageBytes.Length);
        System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);

        string fileName = Server.MapPath("~/Data/").ToString() + "try1" + ".jpeg";
        image.Save(fileName);

        Request.InputStream.Close();


    }
    else
    {
    }

    }
beerBear
  • 969
  • 2
  • 17
  • 41
  • Why not just send the image file as-is rather than as a base64 encoded string? The base64 string will actually be a larger payload than the bytes of the file. – Tap May 23 '13 at 17:06
  • @Tap Thanks for replying..but this one is just a trial run. The actual images will be picked up from the SD Card and they'll be of around < ~300KB of 640x480 res so.. :D – beerBear May 23 '13 at 17:10
  • I think it is better to use a WCF instead of .asmx web method. – Sreekanth Karumanaghat Oct 15 '13 at 06:16

2 Answers2

1

You're not actually setting the name/value pair to the POST. You're merely sending the IMAGE as a base64 string.

Try something like this:

httpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> parms;
httpclient = new DefaultHttpClient();
httppost = new HttpPost(Your Url Here);

params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("image", BASE_64_STRING);

httppost.setEntity(new UrlEncodedFormEntity(params);
HttpResponse resp = httpclient.execute(httppost);
Stephen Wrighton
  • 36,783
  • 6
  • 67
  • 86
1

One of my favourite piece of code.

Android App upload location

I compress the Image (Re size) it just to be save side (Code at the end)

Bitmap bitmap = resizeBitMapImage1(exsistingFileName, 800, 600);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,30, stream);
StrictMode.ThreadPolicy policy = new     StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("image_data", Base64.encodeBytes(stream.toByteArray())));

// image_str = null;
stream.flush();
stream.close();
bitmap.recycle();
nameValuePairs.add(new BasicNameValuePair("FileName", FileName));

String url = "http://www.xyz.com/upload.aspx";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response1 = httpclient.execute(httppost);
Log.i("DataUploaderOffline_Image ","Status--> Completed");

ASPX Page Code

 Response.ContentType = "text/plain";
 string c = Request.Form["image_data"];
 string FileName = Request.Form["FileName"];
 byte[] bytes = Convert.FromBase64String(c);

 System.Drawing.Image image;
 using (MemoryStream ms = new MemoryStream(bytes))
 {
      image = System.Drawing.Image.FromStream(ms);
      image.RotateFlip(System.Drawing.RotateFlipType.Rotate90FlipNone);
      String Fname =   FileName + ".jpeg";
      image.Save(Server.MapPath("Image\\" + Fname), System.Drawing.Imaging.ImageFormat.Jpeg);
      Response.End();
 }

*Resize Code *

public static Bitmap resizeBitMapImage1(String filePath, int targetWidth,
        int targetHeight) {
    Bitmap bitMapImage = null;
    try {
        Options options = new Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        double sampleSize = 0;
        Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math
                .abs(options.outWidth - targetWidth);
        if (options.outHeight * options.outWidth * 2 >= 1638) {
            sampleSize = scaleByHeight ? options.outHeight / targetHeight
                    : options.outWidth / targetWidth;
            sampleSize = (int) Math.pow(2d,
                    Math.floor(Math.log(sampleSize) / Math.log(2d)));
        }
        options.inJustDecodeBounds = false;
        options.inTempStorage = new byte[128];
        while (true) {
            try {
                options.inSampleSize = (int) sampleSize;
                bitMapImage = BitmapFactory.decodeFile(filePath, options);
                break;
            } catch (Exception ex) {
                try {
                    sampleSize = sampleSize * 2;
                } catch (Exception ex1) {

                }
            }
        }
    } catch (Exception ex) {

    }
    return bitMapImage;
}
MDMalik
  • 3,951
  • 2
  • 25
  • 39
  • `string c = Request.Form["image_data"]; string FileName = Request.Form["FileName"]; byte[] bytes = Convert.FromBase64String(c);` exactly the interesting part :D +1 and will try this out asap. Thanks a ton :) – beerBear May 23 '13 at 17:12
  • you will definately like it.. 100's of search on google for this code. Believe me.. :D – MDMalik May 23 '13 at 17:17
  • I tried sending an image of ~15KB and of 498x382 in resolution but when I sent it to the server it was expanded to ~56KB in size and 747x573 in resolution :O FYI: I did not used the above resizing code. But I did used this line: `bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);` Is there any reason for that? :( And any alternative so that I can skip this line ? – beerBear May 23 '13 at 18:19
  • 1
    'bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream);' compresses the image. and plus also fills the stream. If you want to skip it. See this question might help http://stackoverflow.com/questions/10191871/converting-bitmap-to-bytearray-android – MDMalik May 23 '13 at 19:30