2015-11-04 196 views

回答

1

我知道这是一个旧帖子,但这里是我发现为其他人可能需要它。

如果您不想将InkCanvas保存为文件或GIF,请在内存中对其进行处理。我实际上有三个选项。请注意,对于其中的一些内容,您需要添加一个对Win2D.uwp的引用,它可以在NuGet上搜索确切的名称。它由微软提供。

  1. 转换的InkCanvas为字节数组:

    private byte[] ConvertInkCanvasToByteArray() 
    { 
        var canvasStrokes = cvsSignature.InkPresenter.StrokeContainer.GetStrokes(); 
    
        if (canvasStrokes.Count > 0) 
        { 
         var width = (int)cvsSignature.ActualWidth; 
         var height = (int)cvsSignature.ActualHeight; 
         var device = CanvasDevice.GetSharedDevice(); 
         var renderTarget = new CanvasRenderTarget(device, width, 
          height, 96); 
    
         using (var ds = renderTarget.CreateDrawingSession()) 
         { 
          ds.Clear(Windows.UI.Colors.White); 
          ds.DrawInk(cvsSignature.InkPresenter.StrokeContainer.GetStrokes()); 
         } 
    
         return renderTarget.GetPixelBytes(); 
        } 
        else 
        { 
         return null; 
        } 
    } 
    
  2. 如果你需要的是像素的字节数组,你做。但是,如果您现在想要生成图像,则可以使用WriteableBitmap来完成此操作。以下是可以调用的同步和异步方法。

    private WriteableBitmap GetSignatureBitmapFull() 
    { 
        var bytes = ConvertInkCanvasToByteArray(); 
    
        if (bytes != null) 
        { 
         var width = (int)cvsSignature.ActualWidth; 
         var height = (int)cvsSignature.ActualHeight; 
    
         var bmp = new WriteableBitmap(width, height); 
         using (var stream = bmp.PixelBuffer.AsStream()) 
         { 
          stream.Write(bytes, 0, bytes.Length); 
          return bmp; 
         } 
        } 
        else 
         return null; 
    } 
    
    private async Task<WriteableBitmap> GetSignatureBitmapFullAsync() 
    { 
        var bytes = ConvertInkCanvasToByteArray(); 
    
        if (bytes != null) 
        { 
         var width = (int)cvsSignature.ActualWidth; 
         var height = (int)cvsSignature.ActualHeight; 
    
         var bmp = new WriteableBitmap(width, height); 
         using (var stream = bmp.PixelBuffer.AsStream()) 
         { 
          await stream.WriteAsync(bytes, 0, bytes.Length); 
          return bmp; 
         } 
        } 
        else 
         return null; 
    } 
    
  3. 最后,这里是我使用的是能够做到位图上的作物,如果你想这样做异步方法。这种方法的关键是注意如何使用这种方法,您不必首先获取像素字节作为数组。只要让从画布的笔触,然后将其直接保存到内存流

    private async Task<WriteableBitmap> GetSignatureBitmapCropped() 
    { 
        try 
        { 
         var canvasStrokes = cvsSignature.InkPresenter.StrokeContainer.GetStrokes(); 
    
         if (canvasStrokes.Count > 0) 
         { 
          var bounds = cvsSignature.InkPresenter.StrokeContainer.BoundingRect; 
          var xOffset = (uint)Math.Round(bounds.X); 
          var yOffset = (uint)Math.Round(bounds.Y); 
          var pixelWidth = (int)Math.Round(bounds.Width); 
          var pixelHeight = (int)Math.Round(bounds.Height); 
    
          using (var memStream = new InMemoryRandomAccessStream()) 
          { 
           await cvsSignature.InkPresenter.StrokeContainer.SaveAsync(memStream); 
    
           var decoder = await BitmapDecoder.CreateAsync(memStream); 
    
           var transform = new BitmapTransform(); 
           var newBounds = new BitmapBounds(); 
           newBounds.X = 0; 
           newBounds.Y = 0; 
           newBounds.Width = (uint)pixelWidth; 
           newBounds.Height = (uint)pixelHeight; 
           transform.Bounds = newBounds; 
    
           var pdp = await decoder.GetPixelDataAsync(
            BitmapPixelFormat.Bgra8, 
            BitmapAlphaMode.Straight, 
            transform, 
            ExifOrientationMode.IgnoreExifOrientation, 
            ColorManagementMode.DoNotColorManage); 
    
           var pixels = pdp.DetachPixelData(); 
    
           var cropBmp = new WriteableBitmap(pixelWidth, pixelHeight); 
    
           using (var stream = cropBmp.PixelBuffer.AsStream()) 
           { 
            await stream.WriteAsync(pixels, 0, pixels.Length); 
           } 
           return cropBmp; 
          } 
         } 
         else 
         { 
          return null; 
         } 
        } 
        catch (Exception ex) 
        { 
         return null; 
        } 
    } 
    

希望这有助于在Windows 10使用的通用时InkCanvas提供一些替代品。

0

当然,只需将笔画容器保存到一个流中并将其写入文件即可。

if (inkCanvas.InkPresenter.StrokeContainer.GetStrokes().Count > 0) 
{ 
    var savePicker = new Windows.Storage.Pickers.FileSavePicker(); 
    savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; 
    savePicker.FileTypeChoices.Add("PNG", new System.Collections.Generic.List<string> { ".png" }); 

    Windows.Storage.StorageFile file = await savePicker.PickSaveFileAsync(); 
    if (null != file) 
    { 
     try 
     { 
      using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite)) 
      { 
       await inkCanvas.InkPresenter.StrokeContainer.SaveAsync(stream); 
      } 
     } 
     catch (Exception ex) 
     { 
     } 
    } 
} 

更多InkCanvas样本可以找到here

+1

的副本是否可能包括整个InkCanvas的区域保存的图像。墨迹笔画的保存会创建一个矩形,该矩形只是整个画布上的一个小切口。 – pasul

+1

这会创建该文件,但它似乎是gif格式而不是png或jpg。 – tagy22

+1

正如tagy22所说,它会以GIF格式创建它,而不是PNG,即使它在文件选择器中选择.png扩展名时也会将其保存。 –

0

你在问什么是采取屏幕快照。在这种情况下,RenderTargetBitmap似乎可以提供帮助。它可以将任意的UIElement渲染成位图。你可以参考我在这个post的回复。

+1

我已经尝试使用RenderTargetBitmap将InkCanvas的内容保存为图像,但问题在于它不适用于UWP(Windows 10)中的InkCanvas。 – pasul