在Windows 10中将InkCanvas笔划保存为png/jpg图像
本文关键字:png jpg 图像 保存 Windows 中将 InkCanvas | 更新日期: 2023-09-27 18:20:34
有没有办法在Windows 10(UWP应用程序)中将InkCanvas
中的笔划保存为png/jpg图像?
我知道这是一篇旧帖子,但以下是我为其他可能需要它的人做这件事的方法。
如果您不想将InkCanvas保存为文件或GIF,请在内存中进行操作。实际上我有三个选择。请注意,对于其中的一些内容,您需要添加对Win2D.uwp的引用,可以在NuGet上搜索该名称。它由微软提供。
-
将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; } }
-
若您只需要一个像素的字节数组,那个么您就完成了。然而,如果你现在想生成一个图像,你可以使用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; }
-
最后,这里有一个异步方法,如果你想在位图上进行裁剪,我可以使用它。这个方法的关键是要注意,使用这个方法,您不必首先将像素字节作为数组。您只需从画布中获取笔划,然后将其直接保存到内存流中
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 Universal中使用InkCanvas时提供一些替代方案。
当然,只需将笔划容器保存到流中并将其写入文件即可。
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示例可以在此处找到。
您想要的是拍摄屏幕快照。在这种情况下,RenderTargetBitmap似乎会有所帮助。它可以将任意UIElement渲染为位图。你可以参考我在这篇文章中的回复。