【问题标题】:UWP: How can I attach an image to an InkCanvas?UWP:如何将图像附加到 InkCanvas?
【发布时间】:2017-04-13 11:17:04
【问题描述】:

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

至于现在我用这个:

<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。

【问题讨论】:

    标签: uwp windows-10 code-behind inkcanvas


    【解决方案1】:

    根据RenderTargetBitmap类的“XAML视觉效果和RenderTargetBitmap捕获能力”:

    无法捕获的内容将在捕获的图像中显示为空白,但同一视觉树中的其他内容仍然可以捕获并呈现(无法捕获的内容的存在不会使该 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      • 2011-03-17
      • 2017-04-11
      • 2019-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多