尝试在点击图像时以编程方式获取uwp中的屏幕截图

时间:2021-10-30 11:31:20

trying to capture screenshot on uwp But some issue is arising,saying

试图在uwp上捕捉截图但是有些问题正在出现,说

1) writable map doesn't contain a definition for Render.

1)可写映射不包含Render的定义。

2) writable map doesn't contain a definition for Save.jpeg

2)可写映射不包含Save.jpeg的定义

3)Type or namespace media library doesn't found. any type of help would be appreciated. Code

3)找不到类型或命名空间媒体库。任何类型的帮助将不胜感激。码

private void Download(object sender, TappedRoutedEventArgs e)
        {
            // Create a WriteableBitmap with height and width same as that of Layoutroot
            WriteableBitmap bmp = new WriteableBitmap(480, 696);

            //Render the layoutroot element on it
            bmp.Render(Scrshot, null);
            bmp.Invalidate();


            //Save the image to Medialibrary

            //create a stream of image
            var ms = new MemoryStream();
            bmp.SaveJpeg(ms, 480, 696, 0, 100);
            ms.Seek(0, SeekOrigin.Begin);


            //every path must be unique
            var filePath = "myfile" + DateTime.Now.ToString();

            //Remember to include Medialib capabilty from WMAppManifest.xml for acessing the Medialibrary
            var lib = new MediaLibrary();
            lib.SavePicture(filePath, ms);

            MessageBox.Show("Saved in your media library!", "Done", MessageBoxButton.OK);
        }

1 个解决方案

#1


0  

Instead of WriteableBitmap use RenderTargetBitmap to create a bitmap representation of a visible UIElement. To save this bitmap as a file you can use this extension method I've created (here's a great example for extension methods):

而不是WriteableBitmap使用RenderTargetBitmap来创建可见UIElement的位图表示。要将此位图保存为文件,您可以使用我创建的此扩展方法(这是扩展方法的一个很好的示例):

public static class RenderTargetBitmapExtensions {
    public static async Task<StorageFile> ToFile(this RenderTargetBitmap renderTargetBitmap, string filename, StorageFolder folder = null, bool overrideExisting = true) {
        if (folder == null) folder = ApplicationData.Current.TemporaryFolder;

        try {
            byte[] pixels = (await renderTargetBitmap.GetPixelsAsync()).ToArray();

            StorageFile outputFile = await folder.CreateFileAsync(filename, overrideExisting ? CreationCollisionOption.ReplaceExisting : CreationCollisionOption.GenerateUnique);
            var bitmapEncodingMode = BitmapEncoder.PngEncoderId;

            using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite)) {
                var encoder = await BitmapEncoder.CreateAsync(bitmapEncodingMode, writeStream);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, 96, 96, pixels);
                await encoder.FlushAsync();
            }
            return outputFile;
        } catch {
            return null;
        }
    }
}

And finally to get the public Images folder (as MediaLibrary is a Silverlight class and does not exist in UWP anymore) you can do the following according to this thread:

最后获取公共Images文件夹(因为MediaLibrary是一个Silverlight类,并且在UWP中不再存在),您可以根据此线程执行以下操作:

StorageFolder picturesLibrary = KnownFolders.PicturesLibrary;
StorageFolder savedPicturesFolder = await picturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);

Note: By default, apps do not have access to the Pictures Library. You must add the capability in Package.appxmanifest. Open Package.appxmanifest and click on the Capabilities tab. There is a checkbox for the Pictures Library.

注意:默认情况下,应用程序无权访问图片库。您必须在Package.appxmanifest中添加该功能。打开Package.appxmanifest并单击Capabilities选项卡。图片库有一个复选框。

So a whole code to do this should be:

所以这样做的整个代码应该是:

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(LayoutRoot, Convert.ToInt32(LayoutRoot.ActualWidth), Convert.ToInt32(LayoutRoot.ActualHeight));

StorageFolder savedPicturesFolder = await KnownFolders.PicturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);

await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder);

Or if you don't want to override existing files, the last line would be:

或者,如果您不想覆盖现有文件,最后一行将是:

await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder, false);

For that you can alternatively create a time-based filename:

为此,您可以创建基于时间的文件名:

string filename = String.Format("downloaded_{0}.jpg", DateTime.Now.ToString("yyyyMMdd_HHmmss"));
await renderTargetBitmap.ToFile(filename, savedPicturesFolder, false);

#1


0  

Instead of WriteableBitmap use RenderTargetBitmap to create a bitmap representation of a visible UIElement. To save this bitmap as a file you can use this extension method I've created (here's a great example for extension methods):

而不是WriteableBitmap使用RenderTargetBitmap来创建可见UIElement的位图表示。要将此位图保存为文件,您可以使用我创建的此扩展方法(这是扩展方法的一个很好的示例):

public static class RenderTargetBitmapExtensions {
    public static async Task<StorageFile> ToFile(this RenderTargetBitmap renderTargetBitmap, string filename, StorageFolder folder = null, bool overrideExisting = true) {
        if (folder == null) folder = ApplicationData.Current.TemporaryFolder;

        try {
            byte[] pixels = (await renderTargetBitmap.GetPixelsAsync()).ToArray();

            StorageFile outputFile = await folder.CreateFileAsync(filename, overrideExisting ? CreationCollisionOption.ReplaceExisting : CreationCollisionOption.GenerateUnique);
            var bitmapEncodingMode = BitmapEncoder.PngEncoderId;

            using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite)) {
                var encoder = await BitmapEncoder.CreateAsync(bitmapEncodingMode, writeStream);
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight, 96, 96, pixels);
                await encoder.FlushAsync();
            }
            return outputFile;
        } catch {
            return null;
        }
    }
}

And finally to get the public Images folder (as MediaLibrary is a Silverlight class and does not exist in UWP anymore) you can do the following according to this thread:

最后获取公共Images文件夹(因为MediaLibrary是一个Silverlight类,并且在UWP中不再存在),您可以根据此线程执行以下操作:

StorageFolder picturesLibrary = KnownFolders.PicturesLibrary;
StorageFolder savedPicturesFolder = await picturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);

Note: By default, apps do not have access to the Pictures Library. You must add the capability in Package.appxmanifest. Open Package.appxmanifest and click on the Capabilities tab. There is a checkbox for the Pictures Library.

注意:默认情况下,应用程序无权访问图片库。您必须在Package.appxmanifest中添加该功能。打开Package.appxmanifest并单击Capabilities选项卡。图片库有一个复选框。

So a whole code to do this should be:

所以这样做的整个代码应该是:

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(LayoutRoot, Convert.ToInt32(LayoutRoot.ActualWidth), Convert.ToInt32(LayoutRoot.ActualHeight));

StorageFolder savedPicturesFolder = await KnownFolders.PicturesLibrary.CreateFolderAsync("Saved Pictures", CreationCollisionOption.OpenIfExists);

await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder);

Or if you don't want to override existing files, the last line would be:

或者,如果您不想覆盖现有文件,最后一行将是:

await renderTargetBitmap.ToFile("filename.jpg", savedPicturesFolder, false);

For that you can alternatively create a time-based filename:

为此,您可以创建基于时间的文件名:

string filename = String.Format("downloaded_{0}.jpg", DateTime.Now.ToString("yyyyMMdd_HHmmss"));
await renderTargetBitmap.ToFile(filename, savedPicturesFolder, false);