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>