如何将 CanvasControl 的内容保存为图像文件
How to save contents of CanvasControl as an image file
我正在使用 Win2D 制作类似绘画的程序。我的 CanvasControl
包含用户绘制的一些文本、图像和一些线条。我想将此 CanvasControl
的全部内容保存为磁盘上的文件(以任何标准图像格式)。我想这样做是因为我想(稍后)在标准 Image
控件中显示它。
我该怎么做?我尝试使用 RenderTargetBitmap
来加载 CanvasControl
(下面的代码)但由于某种原因它会剪切图像并且只制作了一个小的水平顶部图像。
async private void Button_Click(object sender, RoutedEventArgs e)
{
#region (c) rendering UIElement to bitmap code
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(ccDraw); // ccDraw is CanvasControl
// get the pixels
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
// write the pixels to a InMemoryRandomAccessStream
var stream = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
Image iNew = new Image();
iNew.Stretch = Stretch.None;
iNew.Source = bitmap;
gOuter.Children.Add(iNew);
ccDraw.Visibility = Visibility.Collapsed; // hide CanvasControl so we can see added image
#endregion
}
试试这个:
private void SaveCanvasAsImage()
{
Rect yourRect = new Rect(ccDraw.RenderSize);
RenderTargetBitmap rtBitmap = new RenderTargetBitmap((int)yourRect.Right,
(int)yourRect.Bottom, 100d, 100d, System.Windows.Media.PixelFormats.Default);
rtBitmap.Render(ccDraw);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtBitmap));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
ms.Close();
System.IO.File.WriteAllBytes("yourPng.png", ms.ToArray());
}
这是我为自己做的。 imageSize
是图片的大小,例如 var imageSize = new Size(500,500);
var displayInformation = DisplayInformation.GetForCurrentView();
ccDraw.Measure(imageSize);
ccDraw.UpdateLayout();
ccDraw.Arrange(new Rect(0, 0, imageSize.Width, imageSize.Height));
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(ccDraw, Convert.ToInt32(imageSize.Width), Convert.ToInt32(imageSize.Height));
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Screen.jpg", CreationCollisionOption.ReplaceExisting);
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, fileStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
displayInformation.LogicalDpi,
displayInformation.LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
不能直接保存 CanvasControl 的内容。
但是,如果您绘制到中间 CanvasRenderTarget,则可以使用 SaveAsync.
保存它
有关在屏幕外绘制的更多信息,请访问 http://microsoft.github.io/Win2D/html/Offscreen.htm。
绘制到 CanvasRenderTarget 而不是直接绘制到 CanvasControl 还有其他好处 - 最明显的是它允许您进行附加渲染,而不必每次都重新绘制整个显示。
我正在使用 Win2D 制作类似绘画的程序。我的 CanvasControl
包含用户绘制的一些文本、图像和一些线条。我想将此 CanvasControl
的全部内容保存为磁盘上的文件(以任何标准图像格式)。我想这样做是因为我想(稍后)在标准 Image
控件中显示它。
我该怎么做?我尝试使用 RenderTargetBitmap
来加载 CanvasControl
(下面的代码)但由于某种原因它会剪切图像并且只制作了一个小的水平顶部图像。
async private void Button_Click(object sender, RoutedEventArgs e)
{
#region (c) rendering UIElement to bitmap code
var bitmap = new RenderTargetBitmap();
await bitmap.RenderAsync(ccDraw); // ccDraw is CanvasControl
// get the pixels
IBuffer pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
// write the pixels to a InMemoryRandomAccessStream
var stream = new InMemoryRandomAccessStream();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
stream.Seek(0);
Image iNew = new Image();
iNew.Stretch = Stretch.None;
iNew.Source = bitmap;
gOuter.Children.Add(iNew);
ccDraw.Visibility = Visibility.Collapsed; // hide CanvasControl so we can see added image
#endregion
}
试试这个:
private void SaveCanvasAsImage()
{
Rect yourRect = new Rect(ccDraw.RenderSize);
RenderTargetBitmap rtBitmap = new RenderTargetBitmap((int)yourRect.Right,
(int)yourRect.Bottom, 100d, 100d, System.Windows.Media.PixelFormats.Default);
rtBitmap.Render(ccDraw);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtBitmap));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
ms.Close();
System.IO.File.WriteAllBytes("yourPng.png", ms.ToArray());
}
这是我为自己做的。 imageSize
是图片的大小,例如 var imageSize = new Size(500,500);
var displayInformation = DisplayInformation.GetForCurrentView();
ccDraw.Measure(imageSize);
ccDraw.UpdateLayout();
ccDraw.Arrange(new Rect(0, 0, imageSize.Width, imageSize.Height));
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(ccDraw, Convert.ToInt32(imageSize.Width), Convert.ToInt32(imageSize.Height));
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("Screen.jpg", CreationCollisionOption.ReplaceExisting);
using (var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, fileStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
displayInformation.LogicalDpi,
displayInformation.LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
不能直接保存 CanvasControl 的内容。
但是,如果您绘制到中间 CanvasRenderTarget,则可以使用 SaveAsync.
保存它有关在屏幕外绘制的更多信息,请访问 http://microsoft.github.io/Win2D/html/Offscreen.htm。
绘制到 CanvasRenderTarget 而不是直接绘制到 CanvasControl 还有其他好处 - 最明显的是它允许您进行附加渲染,而不必每次都重新绘制整个显示。