2

I am trying to send a .jpg file which is on my android device to my server computer.

To do this, I am converting the picture into a byte array by a java android application, and sending it as an argument to my server computer. I`m doing this by a web service call.

The first function is edited:

public static byte[] ImageConvertion(){

    File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");
    byte[] data;

    try{
        FileInputStream input = new FileInputStream(inputFile);
        ByteArrayOutputStream output = new ByteArrayOutputStream ();

        byte[] buffer = new byte[65535];

        int l;

        while ((l = input.read(buffer)) > 0)
            output.write (buffer, 0, l);

        input.close();
        output.close();

        data = output.toByteArray();
        return data;


    } catch (IOException e) {
        System.err.println(e);
        data=null;
    }
    return data;

}

My web-service is written in ASP.NET (C#) language, and there is a function that takes the byte array as an argument and converts it back into an image on server computer.

[WebMethod]
public void ByteArrayToPicture(byte[] imageData)
{
    using (var ms = new MemoryStream(imageData))
    {
        Image image = Image.FromStream(ms);
        image.Save(@"C:\newImage.jpg");
    }
}

However, I couldn`t do it because of the web-service side. I have debugged it that and it seems that the problem is because of the Image.FromStream() function.

I definitely don`t have any problems with passing the arguments. I think either, the language conflict or the conversion image to byte and vice-verse may be leading the problem. Does anyone has any idea or see something wrong?

I muchly appropriate any help.

Thanks.

2
  • I'm not sure if this is the cause or not, but java's byte is signed (ranges -128 to 127) and C#'s byte is unsigned (ranges 0 to 255). If you want to make C#'s byte match java's, use sbyte instead (though that may not be an option for you). Commented Dec 4, 2014 at 2:50
  • @Pokechu22: the types are different in the two languages, but bytes are bytes. The same bit pattern that represents (for example) -128 in Java represents 128 in C#, but the JPEG decoder on each platform will interpret that bit pattern identically. Neither language is going to do any actual conversion of the byte; the only difference is how math and literals work in each language. Commented Dec 4, 2014 at 3:48

2 Answers 2

5

sorry for my incomplete question, however I want to give some tips whoever is trying to do the same thing.

If anyone is trying to send an image to a server and both side has different platforms, then do not convert the image into byte array!

The reason is, in my case the image which is converted into byte array on Java differs from the byte array on C#. Therefore according to my research it is not possible to gather the image on the server side. The byte array created on Java wont have the right format on C#.

Hence anyone wants data transferring from one language to another, use Base64 encoding. Convert the image into Base64 string on one side and send it as string to the other language. Since Base64 format is same on every language there wont be any problem to reproduce it.

I sold the problem with the following codes:

Bitmap ourbitmap = BitmapFactory.decodeStream(imageStream, null, options);
ByteArrayOutputStream baos = new ByteArrayOutputStream();  
ourbitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);   
byte[] b = baos.toByteArray(); 
test = Base64.encodeToString(b, Base64.DEFAULT); 

This is the code where I get the image and convert it into Base64 string on Java android application,

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

ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
image.Save(@"D:\tmpImage.jpg");

The code above takes the Base64 type string and converts back into an image. This is written in C#.

Sign up to request clarification or add additional context in comments.

3 Comments

Nice answer! But I have question: how are you calling web service in android side? As link, like: http://host/service/upload/base64_string_goes_here ? Because, I'm also faced with this problem, and I wrote my webservice in WCF... my main problem is URL (which I'm calling it in android app). When I'm encoding image to base64 length of URL is longer than 100.000. So, this length isn't allowed in HTTP standarts (it allows max 2000 chars in URL). So, can you help me at this moment?
@MirjalalTalishinski my web service type was an IIS .asmx web service. I was able to pass parameters (int, boolean and string) by using soap-envelope method on android side. Since I don`t have any experience with WCF webservices, I am not capable of giving any advises. Unfortunately with a quick google I see that, Web endpoints send data by XML or JSON, there is no SOAP envelope therefore, if I am not wrong, you are not able to use the soap method on your case...
thank you for response. OK I understand. But if you can please, see this question and tell me what I'm wrong there... (I think WCF and ASMX project a bit same :)) stackoverflow.com/q/31219056
0

With such an incomplete code example and such a vague problem description, it's difficult to know for sure what the problem is.

However, reviewing the code you did post, I see one bug that would be significant if this is really the code you are using. In your Java methodConvertion() method, you have this statement:

data = output.toByteArray();

The problem is that all that does is create a new byte[] object and assign the reference to your local variable named data. That object never leaves the method.

Presumably you have some other code which, after calling methodConvertion(), sends the byte[] object that is referenced by the argument you passed to that method. But that object is just going to be whatever it was before you called the method.

You should instead change your Java code so that it looks like this:

public static byte[] methodConvertion(){
    File inputFile = new File("/storage/emulated/0/IFSpictures/icon-si_strapclamp.jpg");

    try{
        FileInputStream input = new FileInputStream(inputFile);
        ByteArrayOutputStream output = new ByteArrayOutputStream ();

        byte [] buffer = new byte [65536];
        int l;

        while ((l = input.read(buffer)) > 0)
            output.write (buffer, 0, l);

        input.close();
        output.close();

        return output.toByteArray();

    } catch (IOException e) {
        System.err.println(e);
        return null;
    }
}

And then in the caller, you should check the return value and only proceed if the value is not null, reporting the error somehow otherwise.

If that doesn't address your question, you should edit the question so that it has a better code example, and so that you are much more specific about what's wrong. What happens when you run the code, and how is that different from what you expected? Be sure to clearly state any error messages, quoting them exactly, and including any stack traces from exceptions.

2 Comments

Thanks for your reply. I wanted to make my question more simple instead of writing an article ish question. But it apears that the question may be a little bit vague. The bug you have mentioned helped me to get rid of the crashing error. But still I couldnt get any results.
Well, since your question never mentioned a crash in the first place, I guess that's progress. Sorry you didn't feel it was an answer to the question. Please see my last paragraph for advice on how to make your question more answerable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.