2017-04-13 3 views
0

Je dois capturer une photo avec un appareil photo ou la charger à partir d'un fichier dans un canevas qui doit être modifié pour mettre en surbrillance certains éléments après l'avoir enregistré dans un dossier.UWP: Comment joindre une image à un InkCanvas?

Pour l'instant j'utilise ceci:

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

Et voilà comment je reçois l'ensemble des choses de 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; 
} 

Lorsque je capture la photo de la caméra, je mis la source d'image photo, mais lors de la sauvegarde de l'ensemble, il ne sauvegarde que la photo et non les traits de la toile. Mon hypothèse est que je dois joindre en quelque sorte le flux obtenu de la caméra à inkCanvas.

Répondre

0

Selon les « visuels XAML et des capacités de capture de RenderTargetBitmap » de RenderTargetBitmap classe:

contenu qui ne peut pas être capturé apparaîtra comme blanc dans l'image capturée, mais d'autres contenus dans le même arbre visuel peut toujours être capturé et rendu (la présence de contenu qui ne peut pas être capturé n'invalidera pas la totalité de la capture de cette composition XAML).

Il se peut donc que le contenu de InkCanvas ne puisse pas être capturé. Et il semble qu'il n'y a aucune API peut directement capturer un InkCanvas avec une image jointe en même temps. Mais vous pouvez utiliser Win2D. Plus de détails s'il vous plaît référence this thread.

Vous pouvez utiliser la méthode DrawImage combinée à la méthode DrawInk pour les dessiner tous les deux sur CanvasDevice, puis enregistrer la photo et les traits ensemble. Par exemple:

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

code derrière:

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