2015-11-04 2 views

ответ

1

Я знаю, что это старый пост, но вот как я нашел, чтобы сделать это для других, кому это может понадобиться.

Если вы не хотите сохранять InkCanvas в файл или как GIF, чтобы манипулировать им в памяти. У меня есть три варианта ниже. Обратите внимание, что для некоторых из них вам нужно будет добавить ссылку на Win2D.uwp, которую можно найти на NuGet, выполнив поиск именно этого имени. Он предоставляется Microsoft.

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

Надежда это помогает обеспечить некоторые альтернативы при использовании InkCanvas в Windows 10 универсальных.

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 как изображения, проблемы в том, что он не работает для InkCanvas в UWP (Windows 10). – pasul

Смежные вопросы