从字符串加载图像

时间:2011-05-18 06:28:39

标签: c# .net silverlight silverlight-4.0

由于某些数据存储限制(noSQL),我需要将图像存储为字符串。 如何将图像Bitmap序列化为字符串和返回。 我是这样做的:


Uri testImageUri = new Uri("/DictionaryBasedVM;component/test.jpg", UriKind.Relative);
StreamResourceInfo sri = Application.GetResourceStream(testImageUri);            
var stringData = GetString(sri.Stream);
ImageSource = stringData;           

其中

ImageControl
只是xaml中定义的silverlight图像控件。
我使用以下实用程序函数:


        //For testing 
        public static string GetString(Stream stream)
        {
            byte[] byteArray = ReadFully(stream);   
            return Encoding.Unicode.GetString(byteArray,0,byteArray.Length);
        }
        public static byte[] ReadFully(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

以下属性:


        private string _ImageSource = "";
        public string ImageSource
        {
            set
            {
                _ImageSource = value;
                byte[] byteArray = Encoding.Unicode.GetBytes(value);
                MemoryStream imageStream = new MemoryStream(byteArray);
                BitmapImage imageSource = new BitmapImage();
                imageSource.SetSource(imageStream);
                ImageControl.Source = imageSource;
            }
            get
            {
                return _ImageSource;
            }
        }

我收到错误:“灾难性故障(HRESULT异常:0x8000FFFF(E_UNEXPECTED))”如图所示: enter image description here

即使我不将它存储为字符串,我仍然很好奇为什么我不能这样做。

3 个答案:

答案 0 :(得分:2)

Unicode可能不是用于此目的的最佳编码。你可以更好地对byte[]进行Base64编码并存储它。

答案 1 :(得分:1)

您是否尝试过使用Convert.ToBase64StringConvert.FromBase64String方法?我猜unicode GetString / GetBytes不起作用,因为你的字节数组不符合'已知字符'。

答案 2 :(得分:1)

Base64会为字符串添加30%的大小。我不认为这里有必要。只要您不对字符串执行任何操作,就可以安全地将字节“转换”为字符,反之亦然。以下是一些似乎有用的代码:

    // usage example
    string encoded = FileToString("myimage.png");
    Console.WriteLine(s.Length);
    FileFromString(encoded, "copy.png");

    public static void FileFromString(string input, string filePath)
    {
        if (input == null)
            throw new ArgumentNullException("input");

        if (filePath == null)
            throw new ArgumentNullException("filePath");

        using (FileStream stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
        {
            byte[] buffer = FromString(input);
            stream.Write(buffer, 0, buffer.Length);
        }
    }

    public static byte[] FromString(string input)
    {
        if (input == null)
            throw new ArgumentNullException("input");

        char[] cbuffer = input.ToCharArray();
        byte[] buffer = new byte[cbuffer.Length];
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = (byte)cbuffer[i];
        }
        return buffer;
    }

    public static string FileToString(string filePath)
    {
        if (filePath == null)
            throw new ArgumentNullException("filePath");

        using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Write))
        {
            return ToString(stream);
        }
    }

    public static string ToString(Stream input)
    {
        if (input == null)
            throw new ArgumentNullException("input");

        StringBuilder sb = new StringBuilder();
        byte[] buffer = new byte[4096];
        char[] cbuffer = new char[4096];
        int read;
        do
        {
            read = input.Read(buffer, 0, buffer.Length);
            for (int i = 0; i < read; i++)
            {
                cbuffer[i] = (char)buffer[i];
            }
            sb.Append(new string(cbuffer, 0, read));
        }
        while (read > 0);
        return sb.ToString();
    }

但是,存储字符串的系统可能不喜欢包含0或其他特殊数字的字符串。在这种情况下,base64仍然是一个选项。