title author date CreateTime categories
win10 uwp 读取保存WriteableBitmap 、BitmapImage
lindexi
2018-08-10 19:16:51 +0800
2018-2-13 17:23:3 +0800
Win10 UWP

我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap。关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说。主要说的是 BitmapImage 和 WriteableBitmap 、二进制 byte 的互转。

我们先写一个简单的xaml

       <Image x:Name="Img" Height="200" Width="200"
HorizontalAlignment="Center" Source="Assets/SplashScreen.png" ></Image> <Button Margin="10,300,10,10" Content="确定" Click="Button_OnClick" ></Button>

用到的图片是我新建自带的。

保存 WriteableBitmap 到文件

    private static async Task SaveWriteableBitmapImageFile(WriteableBitmap image, StorageFile file)
{
//BitmapEncoder 存放格式
Guid bitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
string filename = file.Name;
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;
}
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(bitmapEncoderGuid, stream);
Stream pixelStream = image.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length); encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)image.PixelWidth,
(uint)image.PixelHeight,
96.0,
96.0,
pixels);
//Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(imgstream);
//Windows.Graphics.Imaging.PixelDataProvider pxprd = await decoder.GetPixelDataAsync(Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8, Windows.Graphics.Imaging.BitmapAlphaMode.Straight, new Windows.Graphics.Imaging.BitmapTransform(), Windows.Graphics.Imaging.ExifOrientationMode.RespectExifOrientation, Windows.Graphics.Imaging.ColorManagementMode.DoNotColorManage); await encoder.FlushAsync();
}
}

从文件读 WriteableBitmap

        private static async Task<WriteableBitmap> OpenWriteableBitmapFile(StorageFile file)
{
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
WriteableBitmap image = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
image.SetSource(stream); return image;
}
}

ImageSource 转byte[]

ImageSource可以是 BitmapImage 、WriteableBitmap,如果是WriteableBitmap ,那么直接转换

WriteableBitmap 转byte[]

bitmap.PixelBuffer.ToArray();

Image 转byte[]

如果我们的 ImageSource 是 BitmapImage ,那么我们不能使用上面的办法,直接保存 WriteableBitmap ,我们可以使用截图

private async Task<string> ToBase64(Image control)
{
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(control);
return await ToBase64(bitmap);
}

如果 ImageSource 是 WriteableBitmap ,直接保存

我们使用 byte[] 在传输时不好,不能用在 http 传输上(不是一定的不能),所以我们就把它转为base64,我提供了很多方法把数组转 base64 ,把文件转为 base64 。代码是 https://codepaste.net/ijx28i 抄的。

//WriteableBitmap 转 byte[]
private async Task<string> ToBase64(WriteableBitmap bitmap)
{
var bytes = bitmap.PixelBuffer.ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
} private async Task<string> ToBase64(StorageFile bitmap)
{
var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
var decoder = await BitmapDecoder.CreateAsync(stream);
var pixels = await decoder.GetPixelDataAsync();
var bytes = pixels.DetachPixelData();
return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
} private async Task<string> ToBase64(RenderTargetBitmap bitmap)
{
var bytes = (await bitmap.GetPixelsAsync()).ToArray();
return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
} private async Task<string> ToBase64(byte[] image, uint height, uint width, double dpiX = 96, double dpiY = 96)
{
// encode image
var encoded = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, height, width, dpiX, dpiY, image);
await encoder.FlushAsync();
encoded.Seek(0); // read bytes
var bytes = new byte[encoded.Size];
await encoded.AsStream().ReadAsync(bytes, 0, bytes.Length); // create base64
return Convert.ToBase64String(bytes);
} private async Task<ImageSource> FromBase64(string base64)
{
// read stream
var bytes = Convert.FromBase64String(base64);
var image = bytes.AsBuffer().AsStream().AsRandomAccessStream(); // decode image
var decoder = await BitmapDecoder.CreateAsync(image);
image.Seek(0); // create bitmap
var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
await output.SetSourceAsync(image);
return output;
}

上面代码出处:https://codepaste.net/ijx28i

从文件读 BitmapImage

        private async Task<BitmapImage> OpenBitmapImageFile(StorageFile file)
{
var fileStream = await file.OpenReadAsync();
var bitmap = new BitmapImage();
await bitmap.SetSourceAsync(fileStream);
return bitmap;
}

BitmapImage 转 WriteableBitmap

我使用http://www.cnblogs.com/cjw1115/p/5164327.html 大神的,直接转WriteableBitmap bitmap = imageSource as WriteableBitmap;bitmap为null,于是我在网上继续找,好像没看到 UWP 的可以转,只有win7的

其实大神有说,Image的 Source是 WriteableBitmap ,于是他就能转。

UWP的 BitmapImage 不能转换为 byte[] 或 WriteableBitmap 。这句话是错的。


2017年1月4日21:45:37


我后来过了几个月,发现我们的 BitmapImage 可以转 byte[]

我们可以通过拿 BitmapImage 的 UriSource 把它转为 WriteableBitmap ,可以使用截图获得 BitmapImage。

如果想要使用 BitmapImage 的 UriSource 转为 WriteableBitmap,需要 WriteableBitmapEx 。他是在 WPF 就被大家喜欢的库。如何安装 WriteableBitmapEx ,其实有了Nuget 基本没问题。

搜索 WriteableBitmapEx Nuget

然后搜索到了,我们要什么,好像我也不知道。

我就知道可以使用 WriteableBitmap image = await BitmapFactory.New(1, 1).FromContent((BitmapImage).UriSource);

那么转 byte[] 如何做,有了 WriteableBitmap ,下面的我也不知道,不要问我。

如果使用 BitmapImage 图片是 SetSource,那么我也不会。

获取图片中鼠标点击的颜色

获取鼠标点击的那个点,图片的颜色。那么图片之外,界面呢?其实我们还可以把界面截图,然后获取。

那么我们需要首先在 Image 使用 Tap ,假如图片 source 是 BitmapImage

前提安装 WriteableBitmapEx ,假如我们的 ViewModel有一个 BitmapImage 的图片 Image ,于是我们可以使用

            var position = e.GetPosition(sender as UIElement); //鼠标点击的在哪

            WriteableBitmap image = await BitmapFactory.New(1, 1).FromContent((View.Image).UriSource); //我上面说的如何把 BitmapImage 转 WriteableBitmapEx

            var temp = image.GetPixel((int) position.X, (int) position.Y);

            string str = $"R: {temp.R} G: {temp.G} B: {temp.B} ";

获得图片中鼠标点击的颜色。这个方法有时炸了,都是 255 。

代码:https://github.com/lindexi/UWP/tree/master/uwp/src/ImageMoseClick

获取Dpi

可以使用下面代码获取图片DPI。

我的图片从解决方案获得,大家可以从任意的位置获取,只要可以转换为 IRandomAccessStream

var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/lindexi.png"));
using (IRandomAccessStream stream = await file.OpenReadAsync())
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.PngDecoderId, stream);
var DpiX = decoder.DpiX;
var DpiY = decoder.DpiY;
}

如果需要保存网络图片到本地,请到win10 uwp 存放网络图片到本地

参见:http://www.cnblogs.com/cjw1115/p/5164327.html

http://www.cnblogs.com/yuanforprogram/p/4819307.html

http://stackoverflow.com/questions/41439543/how-can-i-get-the-pixel-color-of-an-image-at-the-current-pointer-position-in-a-u

http://www.cnblogs.com/mqxs/p/5707620.html

2018-8-10-win10-uwp-读取保存WriteableBitmap-、BitmapImage的更多相关文章

  1. win10 uwp 读取保存WriteableBitmap 、BitmapImage

    我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap.关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说.主要说的 ...

  2. win10 uwp 读取文本GBK错误

    本文讲的是解决UWP文本GBK打开乱码错误,如何去读取GBK,包括网页GBK.最后本文给出一个方法追加文本. 我使用NotePad记事本保存文件,格式ASCII,用微软示例打开文件方式读取,出现错误 ...

  3. win10 uwp 读取resw资源文件

    ResourceContext resourceContext = ResourceContext.GetForViewIndependentUse(); ResourceMap resourceMa ...

  4. win10 uwp 入门

    UWP是什么我在这里就不说,本文主要是介绍如何入门UWP,也是合并我写的博客. 关于UWP介绍可以参见:http://lib.csdn.net/article/csharp/32451 首先需要申请一 ...

  5. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  6. win10 uwp 使用 Microsoft.Graph 发送邮件

    在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...

  7. win10 UWP 序列化

    将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. .NET Framewor ...

  8. 【广告】win10 uwp 水印图床 含代码

    本文主要是广告我的软件. 图床可以加速大家写博客上传图片的时间,通过简化我们的操作来得到加速. 在写博客的时候,我们发现,我们需要上传一张图片,需要先打开图片,然后选择本地图片,然后上传. 但是我经常 ...

  9. win10 uwp 商业游戏

    本文告诉大家去做一个商业游戏,游戏很简单,几乎没有什么技术 游戏的开始,需要添加框架库,于是引用我自己写的库. 首先是创建一个启动页面,这个页面是显示启动的. 在显示启动的时候,是需要加载游戏需要使用 ...

  10. 01 mybatis框架整体概况(2018.7.10)-

    01 mybatis框架整体概况(2018.7.10)- F:\廖雪峰 JavaEE 企业级分布式高级架构师课程\廖雪峰JavaEE一期\第一课(2018.7.10) maven用的是3.39的版本 ...

随机推荐

  1. 转: CentOS上安装LAMP之第二步:PHP环境及安装过程报错解决方案(纯净系统环境)

    最近有空就配置CentOS系统上的AMP环境,现在配置到PHP环境了 多话不说上传送门:http://blog.csdn.net/zhangatle/article/details/77447653 ...

  2. web前端学习(三)css学习笔记部分(4)-- CSS选择器详解

    4.  元素选择器详解 4.1  元素选择器 4.2  选择器分组 用英文逗号","相连,使用相同的样式表 使用通配符对所有元素进行通用设定. 4.3  类选择器详解 4.3.1. ...

  3. javascript中uber实现子类访问父类成员

    function Animal(){} Animal.prototype={ name:"animal", toString:function(){ console.log(thi ...

  4. LintCode刷题笔记-- Distinct Subsequences

    标签:动态规划 题目描述: Given a string S and a string T, count the number of distinct subsequences of T in S. ...

  5. yum源配置及详解

      红帽系列中,进行软件安装可以有三种方法,编译安装,rpm包安装,和yum源安装.其中yum方法安装最简单,因为它可以自动解决软件包之间的依赖关系... 一.常用yum源 yum源可以来源于多种文件 ...

  6. R语言实现Xbar-R控制图

    R语言实现Xbar-R控制图 Xbar-R控制图在质量管理中主要用于对计量数据进行检测,以达到控制对象质量的目的. 虽然用Excel可以轻松实现控制图的操作,不过作为R软件初学者,我试着用仅有的一点R ...

  7. 2019-9-2-dotnet-命名管道名字长度限制

    title author date CreateTime categories dotnet 命名管道名字长度限制 lindexi 2019-09-02 11:54:50 +0800 2019-09- ...

  8. bzoj3732 Network(NOIP2013 货车运输)

    Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_ ...

  9. Apache CarbonData1.3简介

    CarbonData是一种高性能大数据存储方案,支持快速过滤查找和即席OLAP分析,已在20+企业生产环境上部署应用,其中最大的单一集群数据规模达到几万亿.针对当前大数据领域分析场景需求各异而导致的存 ...

  10. 使用php simple html dom parser解析html标签

    转自:http://www.blhere.com/1243.html 使用php simple html dom parser解析html标签 用了一下 PHP Simple HTML DOM Par ...