user2528880
user2528880

Reputation: 119

Converting from string to Image in C#

I am trying to convert a Unicode string to an image in C#. Each time I run it I get an error on this line

Image image = Image.FromStream(ms, true, true);

that says: ArgumentException was unhandled by user code. Parameter is not valid. Any ideas why this is happening? Below is the rest of the function.

public Image stringToImage(string inputString)
    {
        byte[] imageBytes = Encoding.Unicode.GetBytes(inputString);
        MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);

        ms.Write(imageBytes, 0, imageBytes.Length);
        Image image = Image.FromStream(ms, true, true);

        return image;
    }

Upvotes: 11

Views: 64539

Answers (5)

r.mirzojonov
r.mirzojonov

Reputation: 1249

May this can help you:

public Bitmap stringToImage(string inputString)
{
   byte[] imageBytes = Encoding.Unicode.GetBytes(inputString);
   using (MemoryStream ms = new MemoryStream(imageBytes))
   {
       return new Bitmap(ms);
   }
}

Upvotes: 5

terrybozzio
terrybozzio

Reputation: 4530

With string you might get loss of data,i will just post example on converting image to byte array and array to image again,and after image to byte array,to string and back,without loss of data.

            MemoryStream ms = new MemoryStream();
            Image.FromFile(@"C:\..\..\..\img.jpg").Save(ms,ImageFormat.Jpeg);
            byte[] bytes = ms.ToArray();
            MemoryStream ms1 = new MemoryStream(bytes);
            Image NewImage = Image.FromStream(ms1);
            NewImage.Save(@"C:\..\..\..\img1.jpg");

try this out and it might help you produce what you need.

trying to convert to string and back,better use base64.

            MemoryStream ms = new MemoryStream();
            Image.FromFile(@"C:\..\..\..\img.jpg").Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] bytes = ms.ToArray();
            string byteString = Convert.ToBase64String(bytes);
            byte[] NewBytes = Convert.FromBase64String(byteString);
            MemoryStream ms1 = new MemoryStream(NewBytes);
            Image NewImage = Image.FromStream(ms1);

This should give you the outcome you need.

 MemoryStream ms = new MemoryStream();
    Image.FromFile(@"C:\..\..\..\img.jpg").Save(ms,ImageFormat.Jpeg);
    byte[] bytes = ms.ToArray();
    string byteString = Convert.ToBase64String(bytes);

then when you pass this string into your method...

    public Image stringToImage(string inputString)
    {
         byte[] NewBytes = Convert.FromBase64String(inputString);
         MemoryStream ms1 = new MemoryStream(NewBytes);
         Image NewImage = Image.FromStream(ms1);

         return NewImage;
     }

Upvotes: 0

antiduh
antiduh

Reputation: 12435

You're getting an image as a string, out of ldap? I'm pretty sure if that was true, the string would actually be base64 encoded, and in that case contains bytes that represent actual characters, and not image data.

Could you post a snippit of the string you're getting?

If it's true, you need to take the string and turn it a byte[] by un-base64'ing it, and then use the byte array to make the image. Combined with @JonBenedicto's code:

public Image stringToImage(string inputString)
{
    byte[] imageBytes = Convert.FromBase64String(inputString);
    MemoryStream ms = new MemoryStream(imageBytes);

    Image image = Image.FromStream(ms, true, true);

    return image;
}

Upvotes: 3

Jeff Foster
Jeff Foster

Reputation: 44746

Unicode doesn't encode all possible byte sequences that you'll need to represent an image.

byte[] -> String -> byte[] is a transformation that just won't work for many given sequences of bytes. You'll have to use a byte[] throughout.

For example, if you read the bytes, convert them to UTF-16 then it's possible that byte sequences will be discarded as invalid. Here's an example of an invalid byte sequence from UTF-16.

Code points U+D800 to U+DFFF[edit] The Unicode standard permanently reserves these code point values for UTF-16 encoding of the lead and trail surrogates, and they will never be assigned a character, so there should be no reason to encode them. The official Unicode standard says that all UTF forms, including UTF-16, cannot encode these code points.

Upvotes: 8

Jon Benedicto
Jon Benedicto

Reputation: 10582

Take out your call that writes to the MemoryStream. The constructor call that accepts a byte array automatically puts the contents of the byte array into the stream. Otherwise your stream contains 2 copies of the raw data. In addition, the call to Write will leave the stream's position at the end of stream, so there is no data that the FromStream call can read.

So it would be:

public Image stringToImage(string inputString)
{
    byte[] imageBytes = Encoding.Unicode.GetBytes(inputString);

    // Don't need to use the constructor that takes the starting offset and length
    // as we're using the whole byte array.
    MemoryStream ms = new MemoryStream(imageBytes);

    Image image = Image.FromStream(ms, true, true);

    return image;
}

Upvotes: 3

Related Questions