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

UWP:如何将图像附加到InkCanvas?,uwp,windows-10,code-behind,inkcanvas,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="

我必须用相机拍摄一张照片,或者将它从文件中加载到画布中,在保存到文件夹后,画布应该进行编辑以突出显示上面的某些内容

至于现在,我用的是:

<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;
}
公共静态异步任务RenderToRandomAccessStream(此UIElement)
{
RenderTargetBitmap rtb=新建RenderTargetBitmap();
等待rtb.RenderAsync(元素);
var pixelBuffer=await rtb.GetPixelsAsync();
var pixels=pixelBuffer.ToArray();
//用于以正确的DPI进行渲染
var displayInformation=displayInformation.GetForCurrentView();
var stream=新的InMemoryRandomAccessStream();
var encoder=await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId,stream);
编码器.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.预乘,
(uint)rtb.PixelWidth,
(uint)rtb像素高度,
displayInformation.RawDpiX,
displayInformation.RawDpiY,
像素);
等待编码器。FlushAsync();
stream.Seek(0);
回流;
}
当我从相机中捕获照片时,我将图像源设置为photo,但当保存整个内容时,它只保存照片,而不保存画布上的笔划。我的假设是,我必须以某种方式将从摄影机获得的流附加到inkCanvas。

根据类的“XAML视觉效果和渲染目标位图捕获功能”:

无法捕获的内容将在捕获的图像中显示为空白,但同一视觉树中的其他内容仍可以捕获并呈现(无法捕获的内容的存在不会使该XAML合成的整个捕获无效)

因此,
InkCanvas
的内容可能无法捕获。似乎没有API可以直接捕获同时附加图像的
InkCanvas
。但是你可以用。更多详情请参考

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

<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();
}