美文网首页
uwp开发:截取当前屏幕中需要的图像并保存

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

作者: 搬砖的包工头 | 来源:发表于2019-01-21 13:59 被阅读0次

     

    在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。共同学习交流。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/lxdcjqtx.html