首页 » IT学院 » 正文

uwp开发:截取当前屏幕中需要的图像并保存至应用内存储

本文地址:http://www.zmy123.cn/?p=1257

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

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

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

x

首先贴上前台代码:

cc

可以看到,图片上面显示的文字是和图片分开的。文字是覆盖在图片上的,如果直接下载图片,将不会有文字,所以这不是我需要的结果。最简单的方法还是上面说的,直接获取如图所示的子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文件夹下。

QQ截图20160621030809

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

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

QQ截图20160621031305

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

QQ截图20160621031441

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

后台:

QQ截图20160621031806

前台:

QQ截图20160621032524

我解释一下步骤:

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

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

QQ截图20160621032747

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

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

青春有梦,勇敢去追。

——IT追梦园

本文共 1 个回复

  • lindexi_gd 2016/09/19 11:35

    多谢

发表评论