博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MetroApp保存UIEment为图片
阅读量:4978 次
发布时间:2019-06-12

本文共 2772 字,大约阅读时间需要 9 分钟。

  写本文的起因是想截取Metro App画面作为图片来使用Win8的共享。

  话说自从大MS的客户端UI技术进入XAML时代之后,每次截屏的代码都不太一样,无论silverlight、WPF还是Windows Phone都不完全一样,搞得我头昏脑胀,每次都要搜索一下才写的出来。反观Winform许久未写,如何截屏我还记得一清二楚……真是尴尬……顺带吐槽Metro的各种奇葩Stream类,那跟.NET的Stream类互转那叫一个惨烈和别扭啊。

  花开两头,各表一枝。接下来我们进入今天的正题——如何在Metro下截屏,我再吐槽一下MS,这个截屏用的API似乎Win8.1才开放,还在用Win8的话还是撸撸睡吧……

  首先我们要用到一个奇葩类,这次真的不是WriteableBitmap了,这次的主角是叫做RenderTargetBitmap。

var bitmap = new RenderTargetBitmap();            await bitmap.RenderAsync(this.rootGrid);            IBuffer buffer = await bitmap.GetPixelsAsync();            var stream = buffer.AsStream();

  要想转换UIElement到Stream,通过以上几步就可以了,this.rootGrid是一个UIElement控件,也就是我想保存的图像。值得一提的是AsStream是一个扩展方法,记得要添加namespace System.Runtime.InteropServices.WindowsRuntime哟!

  如果是WPF应用,得到Stream之后存为图片文件是很容易的事情了,分分钟秒杀的程度,问题Metro下面还需要再折腾折腾……

  首先你需要创建一个StorageFile来存放这个图片,一个比较容易的方式是使用FileSavePicker。

FileSavePicker savePicker = new FileSavePicker();            savePicker.SuggestedStartLocation = PickerLocationId.Desktop;            savePicker.FileTypeChoices.Add("Bitmap", new List
() { ".png" }); savePicker.SuggestedFileName = "New Bitmap"; StorageFile savedItem = await savePicker.PickSaveFileAsync();

  接下来你可能会想StorageFile也有了,Stream也有了,应该往StorageFile里写Stream就行了。

  可惜不是,直接使用FileIO.WriteBufferAsync的方法来写入图片文件是不行的。文件会无法作为图片正常显示。

  我们需要使用BitmapEncoder来写入Stream,而WinRT下的这个BitmapEncoder,又需要WinRT的IRandomAccessStream才能使用。

Guid encoderId = BitmapEncoder.PngEncoderId;                IRandomAccessStream fileStream = await savedItem.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(encoderId, fileStream);                byte[] pixels = new byte[pixelStream.Length];                pixelStream.Read(pixels, 0, pixels.Length);                //pixal format shouldconvert to rgba8                for (int i = 0; i < pixels.Length; i += 4)                {                    byte temp = pixels[i];                    pixels[i] = pixels[i + 2];                    pixels[i + 2] = temp;                }                encoder.SetPixelData(                 BitmapPixelFormat.Rgba8,                 BitmapAlphaMode.Straight,                 (uint)bitmap.PixelWidth,                 (uint)bitmap.PixelHeight,                 96, // Horizontal DPI                 96, // Vertical DPI                 pixels);                await encoder.FlushAsync();

  本篇我们简单讨论了如何在MetroApp下截屏保存图片,下篇会根据本篇的成果来讨论一下Win8.1如何共享截屏的图片。同时会简单的提到.NET的Stream和WinRT的Stream的转换。

本篇的参考资料:

Windows 8.1 Apps with XAML and C# Unleashed

  这本书是Google搜索出了某个章节正好提到了RenderTargetBitmap,这会貌似又打不开了,感谢方校长八辈祖宗!这书出中文版了可以买一本!

 

  图片文件BitmapEncoder是学习自这位仁兄的文章!

韦恩卑鄙

  该参考资料明确指出了直接FileIO.WriteBufferAsync写入是不行的。

 

 

转载于:https://www.cnblogs.com/manupstairs/p/3556642.html

你可能感兴趣的文章
Oracle RMAN备份
查看>>
实时监听输入框值变化的完美方案:oninput & onpropertychange
查看>>
【C】枚举用例分析
查看>>
Python中几种数据的常用内置方法
查看>>
安卓点击事件语法
查看>>
NOIP2012模拟赛第三弹
查看>>
7.22武汉日全食自拍留念
查看>>
[转帖]mimikatz 学习
查看>>
IIS 使用 HTTP重定向 修改 默认主页
查看>>
教程笔记《JavaScript深入浅出》
查看>>
MySQL——安装
查看>>
【转】移动端常用的四个框架
查看>>
[转载]delete指针之后应该赋值NULL
查看>>
thinkphp3.2导出
查看>>
OO第三阶段总结
查看>>
oracle分页查询
查看>>
windows rap环境搭建
查看>>
找出第3名学生的成绩
查看>>
[转载]typedef常见用法
查看>>
MVC我来了
查看>>