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);
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.
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;
}
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;
}
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;
}
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);
}
}