2015-11-04 199 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