各种流的转换
关于流的转换,估计每个程序员都会频繁遇到。并且因为 Nokia Imaging SDK 支持 Windows Phone、
Windows 8 开发,所以支持流的格式有很多,为了备用,今后会在本文中补充各种流的格式转换。
1、System.IO.Stream 类型转换为 Windows.Storage.Streams.IBuffer:
void StreamToIBuffer(Stream stream, IBuffer ibuffer) { using (MemoryStream memory = new MemoryStream()) { memory.Position = 0; stream.Position = 0; // 注意流的位置设置 0 stream.CopyTo(memory); // 通过 MemoryStream 的此方法,把 Stream 对象转换为 IBuffer ibuffer = memory.GetWindowsRuntimeBuffer(); } }
MemoryStream.GetWindowsRuntimeBuffer() 是 MemoryStream 类的扩展方法,需要添加 System.Runtime.InteropServices.WindowsRuntime
命名空间。
2、Windows.Storage.Streams.IBuffer 转换成 System.IO.Stream :
void IBufferToStream(Windows.Storage.Streams.IBuffer ibuffer, Stream stream) { //stream = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.AsStream(ibuffer); //或者 stream = ibuffer.AsStream(); }
IBuffer.AsStream() 是 IBuffer 的扩展方法,需要添加 System.Runtime.InteropServices.WindowsRuntime 命名空间。
3、System.IO.Stream 转换成 System.Byte :
void StreamToBytes(Stream stream, byte[] bytes) { // stream.Position = 0; 流的位置设置为 0 using (MemoryStream ms = new MemoryStream()) { byte[] buffer = new byte[8 * 1024]; int read = 0; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } bytes = ms.ToArray(); } }
或者
public byte[] StreamToBytes(Stream stream) { // 设置当前流的位置为流的开始 stream.Seek(0, SeekOrigin.Begin); byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, bytes.Length); return bytes; }
4、 System.Byte 转换成 System.IO.Stream :
void BytesToStream(Stream stream, byte[] bytes) { stream = new MemoryStream(bytes); }
5、IBuffer 转换成、 byte [] :
static byte[] BufferToBytes(IBuffer buf) { using (var dataReader = DataReader.FromBuffer(buf)) { var bytes = new byte[buf.Capacity]; dataReader.ReadBytes(bytes); return bytes; } }
6、 byte [] 转换成 IBuffer :
static IBuffer BytesToBuffer(byte[] bytes) { using (var dataWriter = new DataWriter()) { dataWriter.WriteBytes(bytes); return dataWriter.DetachBuffer(); } }
7、Windows 运行时的流和 .NET 中的流互转,使用 System.IO 命名空间中的扩展方法:
// 将 Windows 运行时的 随机访问流 转换为 .NET 中的流 public Stream RandomStream_to_Stream(InMemoryRandomAccessStream randomStream) { Stream stream = randomStream.AsStream(); return stream; } // 将 .NET 中的流,转换为 Windows 运行时 RandomAccessStream public InMemoryRandomAccessStream Stream_to_RandomStream(Stream stream) { IRandomAccessStream randomStream = stream.AsRandomAccessStream(); return randomStream as InMemoryRandomAccessStream; }
8、使用 Windows.Security.Cryptography.CryptographicBuffer 类进行 byte[] 与 IBuffer 的互转:
9、在 WebView中,通过 byte[] 的方式显示 Gif图片:
var imgLoginCode = new WebView(); this.imgLoginCode.ScriptNotify += ImgLoginCode_ScriptNotify; IBuffer buffer = await codeBll.Open(null, null, current_qc005); // 获取 Gif图片 if (buffer != null) { // 在 WebView 中加载 gif 图片参考:https://code.msdn.microsoft.com/windowsapps/Loading-Image-into-WebView-a3f68921 var stream = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.AsStream(buffer); using (var dataReader = new DataReader(stream.AsInputStream())) { var num = await dataReader.LoadAsync((uint)stream.Length); var bytesStr = new byte[num]; //stream.ReadAsync(bytesStr, 0, num); dataReader.ReadBytes(bytesStr); string a = "data:image/jpeg;base64," + Convert.ToBase64String(bytesStr); //<meta name='viewport' content='width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no'/>/> string ImgCode = "<html><header><meta name='viewport' content='width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no'/><style type='text/css'>body {overflow:hidden;margin:0px;padding:0px;border:0px}</style>" + "<script>function getVcode(){ window.external.notify('refresh_vcode')}</script>" + "</heder><body onclick='getVcode()'><img title='验证码看不清' alt='重试' src='" + a + "' style='width:100%;height:100%'/></body></html>"; //imgLoginCode.Visibility = Visibility.Visible; imgLoginCode.NavigateToString(ImgCode); } } private void ImgLoginCode_ScriptNotify(object sender, NotifyEventArgs e) { // 当单击 WebView 中的 gif 时,重新请求验证码 if (e?.Value != null && e.Value.ToString() == "refresh_vcode") Load_VCode(); }
根据 Gif 的 uri 请求图片数据:
class LoginCodeBLL { public async Task<IBuffer> Open(string width, string height, string qc005) { try { using (HttpClient client = new HttpClient()) { string uri = ...; //gif uri IBuffer buffer = await client.GetBufferAsync(new Uri(uri)); return buffer; } } catch (Exception ex) { Debug.WriteLine(ex.Message); return null; } } /* public async Task<string> DownloadImg(string width, string height, string qc005) { string folderName = "albums_images"; string fileName = "VCode.gif"; StorageFolder tileFolder = null; var rootFolder = ApplicationData.Current.TemporaryFolder; string uri = string.Format("http://passport.iqiyi.com/apis/register/vcode.action?static=1&agenttype={0}&QC005={1}", Utility.AgentType, qc005); try { // Windows.Storage.ApplicationData.Current.LocalFolder 或者 TemporaryFolder 中 tileFolder = await rootFolder.GetFolderAsync(folderName); } catch (FileNotFoundException ex) { // 文件夹不存在 Debug.WriteLine(ex.Message); } catch (Exception ex) { Debug.WriteLine(ex.Message); } // 如果本地存储中没有该文件夹,则创建 if (tileFolder == null) { tileFolder = await rootFolder.CreateFolderAsync(folderName); } StorageFile imgFile = null; // 如果本地存储中没有该图片,则从网络下载 try { using (var client = new System.Net.Http.HttpClient()) { byte[] buffer = await client.GetByteArrayAsync(uri); imgFile = await tileFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting); await FileIO.WriteBytesAsync(imgFile, buffer); } } catch (Exception ex) { Debug.WriteLine(ex.Message); } return imgFile.Path; }*/ }