uwp开发:截取当前屏幕中需要的图像并保存

 

在uwp开发中,有时候需要获取当前屏幕中的图像信息,但是又不适合直接截图保存,因为截图会保存整个屏幕的图像,而且,还需要用户会截屏操作。总之不适合获取屏幕中需要的图像信息。注意题目中的“需要的”。

意思是什么呢?就是我们可以获取当前屏幕中任意一个UIElement中的图像。废话不多说,还是以实战场景为例,因为自己最近就遇到了这种情况。

在做《简影UWP》的“电影台词”模块的时候,显示如下: 需求是:是用户点击保存图片,将会把图片和文字一块保存下来,查看的时候,也是当前显示的这样。

首先贴上前台代码:

可以看到,图片上面显示的文字是和图片分开的。文字是覆盖在图片上的,如果直接下载图片,将不会有文字,所以这不是我需要的结果。最简单的方法还是上面说的,直接获取如图所示的子Grid里面的图像信息,这样,就相当于将子Grid部分截图。这正是我需要的结果。

下来正式行动:

用到的类:RenderTargetBitmap 类。

RenderTargetBitmap类可以实现将UI元素转化为位图 ,即将UI元素截图,生成一张图片。与截图不同的是,它可以定义UIElement,这里,我只需要截图的是图片和文字部分,即上面的字Grid里面的图像信息。

要实现截图并保存到应用内存储,就先要定义文件名:

string desiredName =DateTime.Now.Ticks+".jpg";

再定义文件存储的位置,并创建文件。

StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;            StorageFolder folder=await  applicationFolder.CreateFolderAsync("Pic", CreationCollisionOption.OpenIfExists);            StorageFile saveFile = await folder.CreateFileAsync(desiredName, CreationCollisionOption.OpenIfExists);

接着实例化对象:

RenderTargetBitmap bitmap = new RenderTargetBitmap();

接下来,要指定获取哪个UIelement的图像信息,按照我上面需要的,就是子grid,给它取名PicGird.通过该方法即可指定要获取的位图

await bitmap.RenderAsync(PicGrid);

接着注意:调用RenderAsync方法的时候会初始化RenderTargetBitmap类的对象,但是RenderTargetBitmap类的对象本身并不能作为图片来进行存储,要生成图片文件需要获取到图片的二进制数据。如果你想要获取 DataTransferManager 操作(例如共享协定交换)的图像,或想要使用 Windows.Graphics.Imaging API 将效果应用到图像上或对图像进行转码,那么就需要用到像素数据。如果你想访问RenderTargetBitmap的Pixels数据,你需要在用RenderAsync这个方法将UIElement定义为 RenderTargetBitmap后,再调用RenderTargetBitmap的GetPixelsAsync方法来获得其Pixels数据。该方法返回的是一个IBuffer类型,里面存储的是二进制的位图数。这个IBuffer可以转换为一个Byte数组,数组里面的数据是以BGRA8格式存储的。所以需要获取像素信息:

  var pixelBuffer =await bitmap.GetPixelsAsync();

并做如下转化:

using(var fileStream=await saveFile.OpenAsync(FileAccessMode.ReadWrite))

            {

                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);

                encoder.SetPixelData(BitmapPixelFormat.Bgra8,

                    BitmapAlphaMode.Ignore,

                    (uint)bitmap.PixelWidth,

                    (uint) bitmap.PixelHeight,

                    DisplayInformation.GetForCurrentView().LogicalDpi,

                    DisplayInformation.GetForCurrentView().LogicalDpi,

                    pixelBuffer.ToArray());

                await encoder.FlushAsync();

            }

这样,就可以将UI元素转化为图片并保存了。

完整代码如下:

string desiredName =DateTime.Now.Ticks+".jpg";

            StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;

            StorageFolder folder = await applicationFolder.CreateFolderAsync("Pic", CreationCollisionOption.OpenIfExists);

            StorageFile saveFile = await folder.CreateFileAsync(desiredName, CreationCollisionOption.OpenIfExists);

            RenderTargetBitmap bitmap = new RenderTargetBitmap();

            await bitmap.RenderAsync(PicGrid);

            var pixelBuffer =await bitmap.GetPixelsAsync();

            using(var fileStream=await saveFile.OpenAsync(FileAccessMode.ReadWrite))

            {

                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream);

                encoder.SetPixelData(BitmapPixelFormat.Bgra8,

                    BitmapAlphaMode.Ignore,

                    (uint)bitmap.PixelWidth,

                    (uint) bitmap.PixelHeight,

                    DisplayInformation.GetForCurrentView().LogicalDpi,

                    DisplayInformation.GetForCurrentView().LogicalDpi,

                    pixelBuffer.ToArray());

                await encoder.FlushAsync();

            }

            await new MessageDialog("保存成功").ShowAsync();

这样,就成功地将需要的图片保存下来了,可以去应用文件夹查看:用本地计算机部署,然后执行以上方法。这时候,进入应用存储路径,即如下路径的LocalState文件夹下。

进入以后,可以看到我在代码中创建的文件夹:

然后就可以看到刚才获取到的图片了:

可以看到,我已经成功的将图片保存到了应用存储内。而且上面还是有文字的。正是我要的效果:

最后一步,对于我的应用来说,就是怎么读取,截图一下,我处理读取保存的图片,并显示到界面上的方法:

后台:

前台:

我解释一下步骤:

首先是访问到文件夹路径,然后获取到这个文件夹下的所有文件集合,然后遍历,赋值给要绑定的对象,(这里注意文件夹路径和文件名和文件后缀,一起组成了整个文件的url,将这个url和image控件绑定即可),然后将对象添加进集合,最后将集合绑定到前台的gridview上。OK,大功告成。

最后,我测试一下。多保存几张图片,然后点击显示这个页面

可以看到,成功地显示了我保存的所有图片。o-yes!

这样,整个保存的过程就完美结束了,如果大家有疑问,或者对uwp开发感兴趣,欢迎大家加入我的uwp开发交流群:193148992。共同学习交流。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容