WPF Image解压缩保存为XML中字符串

1. 把WPF image 压缩为字符串并保存在XML中

2. 把XML中的字符串解压为WPF image




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Compression;
using System.IO;
using System.Xml;
using System.Runtime.Serialization.Formatters.Binary;


namespace WpfAppByteZipTest
{
	/// <summary>
	/// MainWindow.xaml 的交互逻辑
	/// </summary>
	public partial class MainWindow : Window
	{
		public MainWindow()
		{
			InitializeComponent();
			string imageFile = @"C:\Documents and Settings\Administrator\My Documents\My Pictures\11.jpg";
		//	BitmapImage imgSource = new BitmapImage(new Uri(imageFile,UriKind.Absolute));
			
			byte[] b = GetPictureData(imageFile);
			BitmapImage myimg = ByteArrayToBitmapImage(b);
			image1.Source = myimg;
		}

		/// <summary>
		/// 将字节数组进行压缩后返回压缩的字节数组
		/// </summary>
		/// <param name="data">需要压缩的数组</param>
		/// <returns>压缩后的数组</returns>
		public static byte[] Compress(byte[] data)
		{
			MemoryStream stream = new MemoryStream();
			GZipStream gZipStream = new GZipStream(stream,CompressionMode.Compress);
			gZipStream.Write(data,data.Length);
			gZipStream.Close();
			return stream.ToArray();
		}

		/// <summary>
		/// 解压字符数组
		/// </summary>
		/// <param name="data">压缩的数组</param>
		/// <returns>解压后的数组</returns>
		public static byte[] Decompress(byte[] bytes)
		{
			using (MemoryStream tempMs = new MemoryStream())
			{
				using (MemoryStream ms = new MemoryStream(bytes))
				{
					GZipStream Decompress = new GZipStream(ms,CompressionMode.Decompress);

					Decompress.CopyTo(tempMs);

					Decompress.Close();

					return tempMs.ToArray();
				}
			}
		}

		public static string Compress(string str)
		{
			//因输入的字符串不是Base64所以转换为Base64,因为HTTP如果不传递Base64则会发生http 400错误
			return Convert.ToBase64String(Compress(Convert.FromBase64String(Convert.ToBase64String(Encoding.Default.GetBytes(str)))));
		}

		public byte[] GetPictureData(string imagepath)
		{
			try
			{
				/**/
				////根据图片文件的路径使用文件流打开,并保存为byte[] 
				FileStream fs = new FileStream(imagepath,FileMode.Open);//可以是其他重载方法 
				byte[] byData = new byte[fs.Length];
				fs.Read(byData,byData.Length);
				fs.Close();
				return byData;
			}
			catch (System.Exception e)
			{
				MessageBox.Show(e.Message);
				return null;
			}

		}

		private static BitmapImage ByteArrayToBitmapImage(byte[] byteArray)
		{
			BitmapImage bmp = null;
			try
			{
				bmp = new BitmapImage();
				bmp.BeginInit();
				bmp.StreamSource = new MemoryStream(byteArray);
				bmp.EndInit();
			}
			catch
			{
				bmp = null;
			}
			return bmp;
		}

		private static byte[] BitmapImageToByteArray(BitmapImage bmp)
		{
			byte[] byteArray = null;
			try
			{
				Stream sMarket = bmp.StreamSource;
				if (sMarket != null && sMarket.Length > 0)
				{
					//很重要,因为Position经常位于Stream的末尾,导致下面读取到的长度为0。 
					sMarket.Position = 0;
					using (BinaryReader br = new BinaryReader(sMarket))
					{
						byteArray = br.ReadBytes((int)sMarket.Length);
					}
				}
			}
			catch
			{
				//other exception handling 
			}

			return byteArray;

		}

	
		string fileXmlPath = @"C:\Documents and Settings\Administrator\My Documents\bytetest.xml";
	
		/// <summary>
		/// 压缩保存为XML
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void btnWrite_Click(object sender,RoutedEventArgs e)
		{
			BitmapImage imgSource = image1.Source as BitmapImage;
			byte[] imageByte = BitmapImageToByteArray(imgSource);

			byte[] sourceData2 = Compress(imageByte);

			string recString = Convert.ToBase64String(sourceData2);
			
			WriteXML(fileXmlPath,recString);

		}

		public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
		{
			string hexString = string.Empty;
			if (bytes != null)
			{
				StringBuilder strB = new StringBuilder();

				for (int i = 0; i < bytes.Length; i++)
				{
					strB.Append(bytes[i].ToString("X2"));
				}
				hexString = strB.ToString();
			}
			return hexString;
		}

		//反过来,16进制格式的string 转成byte[],例如,"ae00cf"转换成0xae00cf,长度缩减一半;"3031" 转成new byte[]{ 0x30,0x31}:

        public static byte[] GetBytes(string hexString,out int discarded)
        {
            discarded = 0;
            string newString = "";
            char c;
            // remove all none A-F,0-9,characters
            for (int i=0; i<hexString.Length; i++)
            {
                c = hexString[i];
				if (Uri.IsHexDigit(c))
                    newString += c;
                else
                    discarded++;
            }
            // if odd number of characters,discard last character
            if (newString.Length % 2 != 0)
            {
                discarded++;
                newString = newString.Substring(0,newString.Length-1);
            }

            int byteLength = newString.Length / 2;
            byte[] bytes = new byte[byteLength];
            string hex;
            int j = 0;
            for (int i=0; i<bytes.Length; i++)
            {
                hex = new String(new Char[] {newString[j],newString[j+1]});
                bytes[i] = HexToByte(hex);
                j = j+2;
            }
            return bytes;
        }

        private static byte HexToByte(string hex)
        {
            byte tt = byte.Parse(hex,System.Globalization.NumberStyles.HexNumber);
            return tt;
        }


		public void WriteXML(string FileName,string imageData)
		{
			XmlDocument doc = new XmlDocument();
			XmlElement Root = doc.CreateElement("Root");//主内容
			doc.AppendChild(Root);
			XmlElement Child1 = doc.CreateElement("attr1");
			XmlAttribute attr1 = doc.CreateAttribute("attr1");
			attr1.Value = imageData;
			Child1.Attributes.Append(attr1);
			Root.AppendChild(Child1);
			doc.Save(FileName);//保存这个xml 网页或exe 都可以
		}


		private void btnRead_Click(object sender,RoutedEventArgs e)
		{
			XmlDocument doc = new XmlDocument();
			doc.Load(fileXmlPath);
			XmlNode root = doc.SelectSingleNode("Root");
			if (root == null)
				return;

			XmlNode Child1 = root.SelectSingleNode("attr1");
			if (Child1 == null)
				return;
			if (Child1.Attributes["attr1"] != null)
			{
				string hexValue = Child1.Attributes["attr1"].Value;
		
				byte[] imageByte = Convert.FromBase64String(hexValue);
		
				imageByte = Decompress(imageByte);

				BitmapImage imgSource = ByteArrayToBitmapImage(imageByte);
				image2.Source = imgSource;

			}
		

		}

	}
}


<Window x:Class="WpfAppByteZipTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="346" Width="531">
    <Grid >
        <Button Content="压缩保存为XML字符串" Height="23" HorizontalAlignment="Left" Margin="54,272,0" Name="button1" VerticalAlignment="Top" Width="151" Click="btnWrite_Click" />
        <Button Content="从XML读并解压图像数据" Height="23" HorizontalAlignment="Left" Margin="270,0" Name="button2" VerticalAlignment="Top" Width="162" Click="btnRead_Click" />
        <Image Height="239" HorizontalAlignment="Left" Margin="270,12,0" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="227" />
        <Image Height="239" HorizontalAlignment="Left" Margin="12,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="243" />
    </Grid>
</Window>

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念