最近做一个小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帮你解决。

最新文章

  1. mybatis 中#{}与${}的区别
  2. DLUTOJ #1394 Magic Questions
  3. NodeJS 各websocket框架性能分析
  4. arcmap+vs2010
  5. Fileupload控件导致500错误
  6. Xming + PuTTY 在Windows下远程Linux主机
  7. C# 保留小数点后两位(方法总结)
  8. BZOJ 2743: [HEOI2012]采花( 离线 + BIT )
  9. CSU1664: 防水堤坝
  10. Axis2 转让Webservice 介面
  11. 配置虚拟主机(windows环境下nginx+php)
  12. Kubernetes环境下的各种调试方法
  13. JSSDK微信自定义分享
  14. 史上最全Android Studio快捷键 -2016-02-28
  15. 20175312 2018-2019-2 《Java程序设计》结对编程练习_四则运算(第二周:整体性总结)
  16. postman引用外部文件中的变量和数据
  17. Linux驱动之同步、互斥、阻塞的应用
  18. ACL访问控制
  19. js获取当前日期时间“yyyy-MM-dd HH:MM:SS”
  20. JSP (tomcat 内置对象)

热门文章

  1. 十、api自动化环境问题及解决方案汇总(持续更新)
  2. OpenCL 矢量存取
  3. Api2Doc生成 Restful API 文档
  4. 股票F10
  5. IIS上架设https网站证书处理备忘
  6. Python3 hex() 函数
  7. TouchEvent里的targetTouches、touches、changedTouches的区别的具体体现是?
  8. mysql启动参数 skip-grant-tables
  9. 关于GLSL中语法和调用规则的一些记录
  10. git查看远程仓库地址