UWP:如何将图像附加到InkCanvas?

时间:2017-04-13 11:17:05

标签: uwp windows-10 code-behind inkcanvas

我必须使用相机拍摄照片或将其从文件加载到画布中,应该进行编辑以突出显示保存到文件夹中的一些内容。

至于现在我用这个:

<Grid x:Name="grid">
    <Image Source="/Assets/stainless-images-110606.jpg" x:Name="ImageToEdit" Stretch="Uniform" />
    <StackPanel Background="LightGreen" Width="700" Height="700" x:Name="StackPanel">
        <InkCanvas x:Name="MyInkCanvas" Width="{Binding Width, ElementName=StackPanel}" Height="{Binding Height, ElementName=StackPanel}"/>
    </StackPanel>
    <InkToolbar TargetInkCanvas="{x:Bind MyInkCanvas}" Name="inkToolbar"/>
    <Button Content="Save" Click="Button_Click" HorizontalAlignment="Right"/>
</Grid>

这就是我从xaml获取全部内容的方式:

public static async Task<IRandomAccessStream> RenderToRandomAccessStream(this UIElement element)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(element);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    // Useful for rendering in the correct DPI
    var displayInformation = DisplayInformation.GetForCurrentView();

    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                         BitmapAlphaMode.Premultiplied,
                         (uint)rtb.PixelWidth,
                         (uint)rtb.PixelHeight,
                         displayInformation.RawDpiX,
                         displayInformation.RawDpiY,
                         pixels);

    await encoder.FlushAsync();
    stream.Seek(0);

    return stream;
}

当我从相机中捕捉照片时,我将图像源设置为照片,但在保存整个内容时,它只保存照片,而不保存画布中的笔画。我的假设是我必须以某种方式将从相机获取的流附加到inkCanvas。

1 个答案:

答案 0 :(得分:0)

根据&#34; XAML视觉效果和RenderTargetBitmap捕获功能&#34; of RenderTargetBitmap class:

  

无法捕获的内容在捕获的图像中显示为空白,但同一视觉树中的其他内容仍然可以捕获并呈现(无法捕获的内容的存在赢得& #39; t使该XAML组合的整个捕获失效。)

因此InkCanvas的内容可能无法捕获。似乎没有API可以直接捕获InkCanvas并同时附加图像。但您可以使用Win2D。更多详情请参阅this thread

您可以使用DrawImage方法结合DrawInk方法在CanvasDevice上绘制它们,然后将照片和笔画保存在一起。例如:

<StackPanel Padding="30" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid>
        <Image
            x:Name="imgbackground"
            Source="/Assets/ob_0_0.png"
            Stretch="None" />
        <InkCanvas x:Name="ink" />
    </Grid>
    <StackPanel Orientation="Horizontal">
        <Button
            x:Name="btnUpdate"
            Margin="10"
            Click="btnUpdate_Click"
            Content="update ink size, click me firstly" />
        <Button
            Margin="10"
            Click="BtnSave_Click"
            Content="Save" />
    </StackPanel>
</StackPanel>

代码背后:

BitmapImage inkimage;
public MainPage()
{
    this.InitializeComponent();
    ink.InkPresenter.InputDeviceTypes = Windows.UI.Core.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)
{            
    StorageFile inputFile = await StorageFile.GetFileFromApplicationUriAsync(inkimage.UriSource);
    CanvasDevice device = CanvasDevice.GetSharedDevice();
    CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (int)ink.ActualWidth, (int)ink.ActualHeight, 96);
    using (var ds = renderTarget.CreateDrawingSession())
    {
        ds.Clear(Colors.White);
        var image = await CanvasBitmap.LoadAsync(device, inputFile.Path, 96);
        ds.DrawImage(image);// Draw image firstly
        ds.DrawInk(ink.InkPresenter.StrokeContainer.GetStrokes());// Draw the stokes
    }

    //Save them to the output.jpg in picture folder
    StorageFolder storageFolder = KnownFolders.SavedPictures;
    var file = await storageFolder.CreateFileAsync("output.jpg", CreationCollisionOption.ReplaceExisting);
    using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        await renderTarget.SaveAsync(fileStream, CanvasBitmapFileFormat.Jpeg, 1f);
    }
}

private void btnUpdate_Click(object sender, RoutedEventArgs e)
{
    //Get the image source that for attaching to the inkcanvas, update the inkcanvas to be same size with image. 
    inkimage = (BitmapImage)imgbackground.Source;
    var imagewidth = inkimage.PixelWidth;
    var imageheight = inkimage.PixelWidth;
    ink.Height = imageheight;
    ink.Width = imagewidth;
    ink.UpdateLayout();
}