Save canvas with background image to WinRT

I want to make a simple drawing application for children with C # for WinRT. The user can select an image and draw a little. But how can I save the image (along with the background)? There are no functions to save the image with the background.

+5
source share
2 answers

I tried using your library to render Canvas to an image file, but I got this error: "Cannot find component. (Exception from HRESULT: 0x88982F50)." The code is as follows:

//SAVE
    private async void saveButton_Click(object sender, RoutedEventArgs e)
    {
        await SaveToFile();
    }

    public async Task SaveToFile()
    {
        var wb = new WriteableBitmap(1, 1);
        await wb.Render(canvas);

        Windows.Storage.Pickers.FileSavePicker save = new Windows.Storage.Pickers.FileSavePicker();
        save.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
        save.DefaultFileExtension = ".jpg";
        save.FileTypeChoices.Add("JPG", new string[] { ".jpg" });
        StorageFile filesave = await save.PickSaveFileAsync();
        await wb.SaveToFile(filesave, Guid.NewGuid());
    }
+2
source

WriteableBitmap WinRT XAML Toolkit , :

using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.UI.Xaml.Media.Imaging;

namespace WinRTXamlToolkit.Imaging
{
    /// <summary>
    /// Extension methods used for saving a WriteableBitmap to a file.
    /// </summary>
    public static class WriteableBitmapSaveExtensions
    {
        /// <summary>
        /// Saves the WriteableBitmap to a png file with a unique file name.
        /// </summary>
        /// <param name="writeableBitmap">The writeable bitmap.</param>
        /// <returns>The file the bitmap was saved to.</returns>
        public static async Task<StorageFile> SaveToFile(
            this WriteableBitmap writeableBitmap)
        {
            return await writeableBitmap.SaveToFile(
                KnownFolders.PicturesLibrary,
                string.Format(
                    "{0}_{1}.png",
                    DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
                    Guid.NewGuid()),
                CreationCollisionOption.GenerateUniqueName);
        }

        /// <summary>
        /// Saves the WriteableBitmap to a png file in the given folder with a unique file name.
        /// </summary>
        /// <param name="writeableBitmap">The writeable bitmap.</param>
        /// <param name="storageFolder">The storage folder.</param>
        /// <returns>The file the bitmap was saved to.</returns>
        public static async Task<StorageFile> SaveToFile(
            this WriteableBitmap writeableBitmap,
            StorageFolder storageFolder)
        {
            return await writeableBitmap.SaveToFile(
                storageFolder,
                string.Format(
                    "{0}_{1}.png",
                    DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
                    Guid.NewGuid()),
                CreationCollisionOption.GenerateUniqueName);
        }

        /// <summary>
        /// Saves the WriteableBitmap to a file in the given folder with the given file name.
        /// </summary>
        /// <param name="writeableBitmap">The writeable bitmap.</param>
        /// <param name="storageFolder">The storage folder.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="options">
        /// The enum value that determines how responds if the fileName is the same
        /// as the name of an existing file in the current folder. Defaults to ReplaceExisting.
        /// </param>
        /// <returns></returns>
        public static async Task<StorageFile> SaveToFile(
            this WriteableBitmap writeableBitmap,
            StorageFolder storageFolder,
            string fileName,
            CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
        {
            StorageFile outputFile =
                await storageFolder.CreateFileAsync(
                    fileName,
                    options);

            Guid encoderId;

            var ext = Path.GetExtension(fileName);

            if (new[] { ".bmp", ".dib" }.Contains(ext))
            {
                encoderId = BitmapEncoder.BmpEncoderId;
            }
            else if (new[] { ".tiff", ".tif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".gif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".jpg", ".jpeg", ".jpe", ".jfif", ".jif" }.Contains(ext))
            {
                encoderId = BitmapEncoder.TiffEncoderId;
            }
            else if (new[] { ".hdp", ".jxr", ".wdp" }.Contains(ext))
            {
                encoderId = BitmapEncoder.JpegXREncoderId;
            }
            else //if (new [] {".png"}.Contains(ext))
            {
                encoderId = BitmapEncoder.PngEncoderId;
            }

            await writeableBitmap.SaveToFile(outputFile, encoderId);

            return outputFile;
        }

        /// <summary>
        /// Saves the WriteableBitmap to the given file with the specified BitmapEncoder ID.
        /// </summary>
        /// <param name="writeableBitmap">The writeable bitmap.</param>
        /// <param name="outputFile">The output file.</param>
        /// <param name="encoderId">The encoder id.</param>
        /// <returns></returns>
        public static async Task SaveToFile(
            this WriteableBitmap writeableBitmap,
            StorageFile outputFile,
            Guid encoderId)
        {
            Stream stream = writeableBitmap.PixelBuffer.AsStream();
            byte[] pixels = new byte[(uint)stream.Length];
            await stream.ReadAsync(pixels, 0, pixels.Length);

            using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
            {
                var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
                encoder.SetPixelData(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Premultiplied,
                    (uint)writeableBitmap.PixelWidth,
                    (uint)writeableBitmap.PixelHeight,
                    96,
                    96,
                    pixels);
                await encoder.FlushAsync();

                using (var outputStream = writeStream.GetOutputStreamAt(0))
                {
                    await outputStream.FlushAsync();
                }
            }
        }
    }
}

WinRTXamlToolkit.Composition , XAML UI, Direct2D, .

+1

All Articles