Search code examples
c#.netuwpwin2d

How do I use the CanvasBitmap.SaveAsync method?


In the Win2D API documentation they say

Saves the entire bitmap to a file with the specified file name, using a default quality level of 0.9 and CanvasBitmapFileFormat.Auto.

It doesn't say where the file is saved or how to choose where the file is saved. I tried playing with the method in order to figure it out but everytime I call it I get an "Access denied" exception error.

                string filename = "Test pic test.png";
        StorageFile TestFile = await PictureFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
        using (IRandomAccessStream strem = await TestFile.OpenAsync(FileAccessMode.ReadWrite))
        {
            await CanvasImage.SaveAsync(filename);
        }

Solution

  • Firstly, this above description is for CanvasBitmap.SaveAsync method. Since Win2D also contains CanvasImage class, I suggest to avoid naming the instance to CanvasImage.

    According to this similar issue:

    In general you can't pass around paths in the user's filesystem (as opposed to special folders like the app package directory) because of the UWP security model: https://learn.microsoft.com/en-us/windows/uwp/files/file-access-permissions

    So that you need to pass the stream directly into SaveAsync, not just the path as a string. In your code snippet you open the file stream but didn't save the stream to the file. Just save the stream to the file it will work. For example:

    CanvasDevice device = CanvasDevice.GetSharedDevice();
    CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, 300, 300, 96);
    using (var ds = renderTarget.CreateDrawingSession())
    {
        ds.Clear(Colors.White);           
        ds.DrawRectangle(155, 115, 80, 30, Colors.Black);
    } 
    CanvasBitmap bit = renderTarget;
    string filename = "Test pic test.png";
    StorageFolder pictureFolder = KnownFolders.SavedPictures;
    var file = await pictureFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
    using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        await bit.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
    }
    

    More details you can reference this blog.