Main Site Documentation

XML : convert string to byte[] for image


#1

Hello all,

I’m trying to communication (with my Fez Cobra) with a service.asmx in SOAP which returns me a description associated to a code (2639 for exemple), including an image jpg.

But the service answer me with a XML description. And my XmlReader only allows me to read strings. So i read my image as a string and I do not know how to convert it to my byte[] which I use to draw my bimap.

I do not need a “normal” conversion from string to byte, as UTF8 or ASCII because in my string I already have the proper values for the byte array. So if I use those, the byte array is not good (for example, I received /9j/… so my string is “/9j/…” and I do not want my byte[] to look like {0x2F, 0x39, …} but as I look on other images loaded from my SD card {0xFF, 0xD8, 0xFF…}

Clue : I have a collegue which maked it works once, but he do not remember the line he wrotte. It was one line I guess, maybe with a “Convert” ?

Thank you for any help you can offer…


#2

I can add that I have made several try :


                /* endless (>5 mn) :
                 buffer = new byte[image.Length];
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = (byte)image[i];
                }
                 * */

                // endless (>5mn) buffer = ConvertBase64.FromBase64String(image);
                // not good (ASCII) : buffer = System.Text.Encoding.UTF8.GetBytes(image);
                // not good (ASCII) : buffer = System.Text.UTF8Encoding.UTF8.GetBytes(image);
                /* not good (ASCII) :
                char[] imageArray = image.ToCharArray();
                buffer = new byte[imageArray.Length];
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = (byte)imageArray[i];
                }
                 * */
                /* Exception
                 buffer = new byte[image.Length];
                for (int i = 0; i < buffer.Length; i++)
                {
                    buffer[i] = byte.Parse(image.Substring(i, 1));
                }
                 * */
                /* Exception
                buffer = new byte[image.Length/2];
                for (int i = 0; i < buffer.Length/2; i++)
                {
                    buffer[i] = byte.Parse(image.Substring(i*2, 2));
                }
                 * */
                /* Not good at all :
                char[] imageArray = image.ToCharArray();
                buffer = new byte[imageArray.Length * 2];
                for (int i = 0; i < imageArray.Length; i = i + 2)
                {
                    buffer[i] = (byte)(imageArray[i] & 0x00FF);
                    buffer[i+1] = (byte)((imageArray[i] & 0xFF00) >> 8 );
                }
                 * */


#3

How long is that image string?? There is a Convert method for this but it was introduced in NET MF 4.2. I know this workaround:

            var data = new byte[4];

            using (var sw = new StreamWriter(new MemoryStream(data)))
                sw.Write("ABCD");

#4

Thank you for your quick response.

And sorry because I forgot an other method I used, quite similar to yours. But the point is that this method also gives me an ascii conversion from char to byte.

So your byte array will be {0x41, 0x42, 0x43, 0x44} where I want it to be… I do not know but so it can be used for a bitmap…

So I need to copy the string into the byte, but wihout ascii conversion.

My other method:



        public static byte[] ConvertStringToBytes(string input)
        {
            MemoryStream stream = new MemoryStream();

            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(input);
                writer.Flush();
            }

            return stream.ToArray();
        }



#5

You need to figure out how you want to convert the string and show an example. There are plenty of ways beside regular ASCII to byte conversion. Here are some examples of converting a string “12”:

[ulist]{ 0x41, 0x42 }
{ 0x12 }
{ 12 }
{ 1, 2 }[/ulist]

Are you sure the string you are trying to covert contains the data you want?


#6

Yes because before the service becomes a service it was a WebServer.

But then it can send me directly the byte[]. Now it is changed into an Asmx Service, I have no choice that to received it through a SOAP enveloppe, which means XML. But the data in it is still the same.

Or maybe I have to find how to decode the XML part from the stream in a byte[] way to keep the stream ina byte[] and not be disturbed by the XMLReader and its ReadString()…


#7

But you are right that when the WebServer sended me the byte[] it was not the same format that now the service…

I have to check values are matching.


#8

The XML data inside SOAP envelope is not binary so even if you get the pure tcp data stream you will get the same.


#9

When you using WebServer you can reply with plain HTTP response containing binary data. WebServices are designed to use XML.


#10

Yes.

But then is Micro Framework able to receive images through XML ??


#11

Try to write the same app using regular .NET Framework and see what result you are getting. I guess you will receive the same as in .NET MF.


#12

OK, I have to change my question…

When I receive my byte[] through the SOAP XML Envelope in byte[] instead of XML, the byte[] is really encoded as a string {0x41, 0x42, 0x43, 0x44 } in your method.

So the UTF8 method are all right to recoved what is send by the service.

But then this byte[] is different from the one I received by the WebServer and makes the DrawImage go on exception…

So do you have any idead of what I have to do on this SOAP byte[] to draw my bitmap with ??


#13

sorry Gralin, I did not see your last answer.

But yes, it is the same on .Net. Even if I call the service with Google Chrome.


#14

I think you have to investigate how to send binary data in a SOAP envelope. Forget about .NET MF for know and try to make a proof of concept using only .NET Framework application.


#15

OK Gralin,

I think you are right.

I’ll try and let you know.

Thank you very much for your support.


#16

Well it works in .Net Framework because I can use _myXmlReader.ReadElementContentAsBase64()…

So now I must find how to do it on MicroFramework, which does not include the ReadElementContentAsBase64() but only have ReadString()…


#17

Take a look at this
http://code.tinyclr.com/project/393/convertbase64-class-issue-resolution/


#18

Hello Architect and thank you for your intervention,

it seems nice but if it works fine on emulator (maybe 1 mn), it takes more than 10 mn (and it is still not done) on my Fez :o !

My picture is a jpg one, of 30 Ko and is 100x100. Is it normal it takes so long ??


#19

I haven’t tried it, so I don’t know. Show your code may be there is a way to optimize it


#20

Well, unfortunately it seems it is the method “FromBase64String” which takes all this time : I have a breakpoint before and another one after to check the buffer I get and I do not get it…



private void LoadFromXml(XmlReader xml, ref byte[] buffer, string balise)
        {
            if (xml.ReadToDescendant(balise))
            {
                string image = xml.ReadString();

                [b]buffer = MyConvertBase64.FromBase64String(image);[/b]
                
            }

            xml.Skip();
        }


But I’m going to do it in step by step to have an idea of what takes so long.