Reputation: 45
trying to capture screenshot on uwp But some issue is arising,saying
1) writable map doesn't contain a definition for Render.
2) writable map doesn't contain a definition for Save.jpeg
3)Type or namespace media library doesn't found. any type of help would be appreciated. Code
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);
}
Upvotes: 0
Views: 573
Reputation: 636
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):
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:
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.
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);
Upvotes: 1