UWP:如何将图像附加到 InkCanvas? [英] UWP: How can I attach an image to an InkCanvas?

查看:43
本文介绍了UWP:如何将图像附加到 InkCanvas?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to capture a photo with camera or loading it from file into a canvas which should be edited for highlighting some stuff on it after that saved into a folder.

至于现在我使用这个:

<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 中获取全部内容的方式:

And this is how I get the whole stuff from 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.

When I capture the photo from camera I set the image source to photo, but when saving the whole stuff it saves only the photo and not the strokes from canvas. My assumption is that I have to somehow attach the stream got from camera to inkCanvas.

推荐答案

根据 RenderTargetBitmap 类:

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

Content that can't be captured will appear as blank in the captured image, but other content in the same visual tree can still be captured and will render (the presence of content that can't be captured won't invalidate the entire capture of that XAML composition).

因此可能是 InkCanvas 的内容不可捕获.并且似乎没有 API 可以直接同时捕获带有图像的 InkCanvas.但是您可以使用 Win2D.更多详情请参考此线程.

So it could be that the content of InkCanvas is not captureable. And it seems like there is no APIs can directly capture a InkCanvas with an image attached at the same time. But you can use Win2D. More details please reference this thread.

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

You could use DrawImage method combined the DrawInk method to draw them both on CanvasDevice, then can save the photo and strokes together. For example:

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

这篇关于UWP:如何将图像附加到 InkCanvas?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆