Displaying a background image on a UWP ink canvas

后端 未结 1 1761
野性不改
野性不改 2020-12-05 21:15

I have an InkCanvas in my UWP app, and would like to display an image (ideally as part of the Canvas, but otherwise, overlay it in some way (the idea being that I can save t

相关标签:
1条回答
  • 2020-12-05 22:12

    So you have couple of problems:

    1. How to draw using InkCanvas over Image control.
    2. How to save the results into a file.

    I'll use simple UWP app in this example, which assumes that you have "sample.jpg" file in your Assets folder, and you have "Pictures Library" capability in your manifest.

    To solve first problem, just put both InkCanvas and Image into same container (like Grid), but remember that order matters:

    <StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid>
            <Image Source="/Assets/sample.jpg"></Image>
            <InkCanvas x:Name="ink"></InkCanvas>
        </Grid>
        <Button Content="Save"
                Width="100"
                Height="25"
                HorizontalAlignment="Center"
                VerticalAlignment="Center" Click="BtnSave_Click"/>
    </StackPanel>
    

    If you put InkCanvas first (like you did in question example) - it won't work. However if put InkCanvas last - all works fine and you can draw over your image.

    Now to solve second problem you need to use Win2D (install nuget Win2D.uwp package), because standard RenderTargetBitmap won't render InkCanvas contents. First draw your original image (take image from original source directly, that is from original file for example), then draw contents of your ink canvas over it. Full code of MainPage (if you add xaml above you will have complete working sample):

    public sealed partial class MainPage : Page {
        public MainPage() {
            this.InitializeComponent();
            // just set some properties of ink canvas, not directly relevant to your question
            ink.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch;
            var attr = new InkDrawingAttributes();
            attr.Color = Colors.Red;
            attr.IgnorePressure = true;
            attr.PenTip = PenTipShape.Circle;
            attr.Size = new Size(4, 10);
            ink.InkPresenter.UpdateDefaultDrawingAttributes(attr);
        }
    
        private async void BtnSave_Click(object sender, RoutedEventArgs e) {
            // grab output file
            StorageFolder storageFolder = KnownFolders.SavedPictures;
            var file = await storageFolder.CreateFileAsync("output.jpg", CreationCollisionOption.ReplaceExisting);
    
            CanvasDevice device = CanvasDevice.GetSharedDevice();
            CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (int) ink.ActualWidth, (int) ink.ActualHeight, 96);
    
            // grab your input file from Assets folder
            StorageFolder appInstalledFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
            StorageFolder assets = await appInstalledFolder.GetFolderAsync("Assets");
            var inputFile = await assets.GetFileAsync("sample.jpg");            
            using (var ds = renderTarget.CreateDrawingSession()) {
                ds.Clear(Colors.White);                
                var image = await CanvasBitmap.LoadAsync(device, inputFile.Path);
                // draw your image first
                ds.DrawImage(image);
                // then draw contents of your ink canvas over it
                ds.DrawInk(ink.InkPresenter.StrokeContainer.GetStrokes());
            }
    
            // save results
            using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) {
                await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Jpeg, 1f);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题