[uwp]ImageSource和byte[]相互转换
最近做一个小app遇到一个问题,到目前还没有比较好的解决方法(可能是我查的资料不够多)
需求如下:
1.把一个Image中的图像保存到字节数组;
2.把字节数组转换为ImageSource,通过Image控件展示图像.
上面两个需求恰恰是相反的过程,为了实现这个,我倒网上找了好多,但基本都是wp7,wp8,wpf的方案,在win10上没法用。。纠结。
后来在知乎日报uwp的源码中发现了一个把ImageSource存储为文件的方法。(github:https://github.com/sherlockchou86/ZhiHuDaily.UWP),感谢作者为win10生态圈的贡献。
代码如下:
public async Task SaveImageAsync(WriteableBitmap image, string filename)
{
try
{
if (image == null)
{
return;
}
Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
if(filename.EndsWith("jpg"))
BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
else if(filename.EndsWith("png"))
BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
else if(filename.EndsWith("bmp"))
BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
else if(filename.EndsWith("tiff"))
BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
else if(filename.EndsWith("gif"))
BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
var folder = await _local_folder.CreateFolderAsync("images_cache", CreationCollisionOption.OpenIfExists);
var file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
Stream pixelStream = image.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, , pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)image.PixelWidth,
(uint)image.PixelHeight,
96.0,
96.0,
pixels);
await encoder.FlushAsync();
}
}
catch
{ }
}
SaveImageAsync
有了这个,我的需求就能解决了,因为在上面的代码中,有一个随机访问流ras,所以我们可以把ras利用拓展方法AsStream()转化为普通的流,然后用Read()或者ReadAsync()读取到字节数组即可。
于是需求一的代码如下:
public static async Task<byte[]> SaveToBytesAsync(this ImageSource imageSource)
{
byte[] imageBuffer;
var localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.ReplaceExisting);
using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
WriteableBitmap bitmap = imageSource as WriteableBitmap;
var stream = bitmap.PixelBuffer.AsStream();
byte[] buffer = new byte[stream.Length];
await stream.ReadAsync(buffer, , buffer.Length);
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, buffer);
await encoder.FlushAsync(); var imageStream = ras.AsStream();
imageStream.Seek(, SeekOrigin.Begin);
imageBuffer = new byte[imageStream.Length];
var re = await imageStream.ReadAsync(imageBuffer, , imageBuffer.Length); }
await file.DeleteAsync(StorageDeleteOption.Default);
return imageBuffer;
}
值得注意的几点:
1.用了拓展方法;
2.ImageSource一般可以通过BitmapImage和WriteableImage来设置,但这儿只能用WriteableImage,因为要用到接口IWriteableBitmap;
3.ras随机访问流转为普通FCL普通流后,用Seek将Positon设置到0,读出的数据出错;
4.注意图像编码的设置,这儿只针对jpeg格式;
5.这是一个投机的办法,先存储为文件,再存储为字节数组,但核心还是一个ras(IRandomAccessSteam).
需求二代码如下:
public static async Task<ImageSource> SaveToImageSource(this byte[] imageBuffer)
{
ImageSource imageSource = null;
using (MemoryStream stream = new MemoryStream(imageBuffer))
{
var ras = stream.AsRandomAccessStream();
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, ras);
var provider = await decoder.GetPixelDataAsync();
byte[] buffer = provider.DetachPixelData();
WriteableBitmap bitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
await bitmap.PixelBuffer.AsStream().WriteAsync(buffer, , buffer.Length);
imageSource = bitmap;
}
return imageSource;
}
注意点如下:
1.解码用的还是jpeg;
2.还是用的WriteableBitmap,主要还是他的接口决定的;
tips:如果照的上面的代码写,某些方法或属性下面还是有红色波浪线的话,记着选中它,然后按Shift+alt+F10,Visual Studio帮你解决。
[uwp]ImageSource和byte[]相互转换的更多相关文章
- 【C#/WPF】Bitmap、BitmapImage、ImageSource 、byte[]转换问题
C#/WPF项目中,用到图像相关的功能时,涉及到多种图像数据类型的相互转换问题,这里做了个整理.包含的内容如下: Bitmap和BitmapImage相互转换. RenderTargetBitmap ...
- dword word byte 相互转换 .xml
pre{ line-height:1; color:#800080; background-color:#d2c39b; font-size:16px;}.sysFunc{color:#627cf6; ...
- C#中string和byte[]相互转换问题解决
本来想讲string转换为byte数组,通过在VS上打 ‘str. “来找,结果半天没发现跳出来的函数中有想要的,哭瞎 /(ㄒoㄒ)/~~ 这回将两种情况都记下来了.... string ---> ...
- WriteableBitmap/BitmapImage/MemoryStream/byte[]相互转换
1 WriteableBitmap/BitmapImage/MemoryStream/byte[]相互转换 2012-12-18 17:27:04| 分类: Windows Phone 8|字号 订 ...
- java 中 image 和 byte[] 相互转换
java 中 image 和 byte[] 相互转换可恶的…………其实也挺好的 只是把好不容易写出来的东西记下来,怕忘了…… 下面,我来介绍一个简单的 byte[] to image, 我们只需要 ...
- String 与 byte[]相互转换
1. 从byte[]转换成string string result = System.Text.Encoding.UTF8.GetString(byteArray); 2.从string 转换成byt ...
- C#中字符串与byte[]相互转换
字符串转换为byte[] 给定一个string,转换为byte[],有以下几种方法. 方法1: static byte[] GetBytes(string str) { byte[] bytes = ...
- C#图像处理:Stream 与 byte[] 相互转换,byte[]与string,Stream 与 File 相互转换等
C# Stream 和 byte[] 之间的转换 一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = 0; Ima ...
- 2015.5.11 string与byte[]相互转换
string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str ); 反过来,byte[]转成stri ...
随机推荐
- Python单例模式实现方法
一 简介 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源 ...
- jeesite快速开发平台(七)----代码生成原理
转自:https://blog.csdn.net/u011781521/article/details/79322942
- CentOS 7 调整 home分区 扩大 root分区
总体过程: 把/home内容备份,然后将/home文件系统所在的逻辑卷删除,扩大/root文件系统,新建/home ,恢复/home内容 1.查看分区 df -h 2.备份home分区文件 tar c ...
- 什么是2MSL
[什么是2MSL] MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃.因为tcp报文( ...
- cp & scp
[cp & scp] Linux为我们提供了两个用于文件copy的命令,一个是cp,一个是scp,但是他们略有不同. cp --- 主要是用于在同一台电脑上,在不同的目录之间来回copy文 ...
- UNITY中有Timer
using UnityEngine; using System.Collections; using System.Timers; public class NewBehaviourScript : ...
- 微信小程序通讯录首字母索引效果,车辆品牌选择列表
效果图: wxml代码: <block wx:for="{{list}}"> <view class='letter' id="letter{{inde ...
- 理解数据库中的undo日志、redo日志、检查点
数据库存放数据的文件,本文称其为data file. 数据库的内容在内存里是有缓存的,这里命名为db buffer.某次操作,我们取了数据库某表格中的数据,这个数据会在内存中缓存一些时间.对这个数据的 ...
- Linux命令:cp (copy)复制文件或目录
复制文件,只有源文件较目的文件的修改时间新时,才复制文件 cp -u -v file1 file2 .将文件file1复制成文件file2 cp file1 file2 .采用交互方式 ...
- Trait 概览
Trait是PHP 5.4引入的新概念,看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么:提供模块化实现.Trait ...