我正在寻找从Windows应用商店应用程序保存画布的方法,我发现:
private void CreateSaveBitmap(Canvas canvas, string filename)
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
(int)canvas.Width, (int)canvas.Height,
96d, 96d, PixelFormats.Pbgra32);
// needed otherwise the image output is black
canvas.Measure(new Size((int)canvas.Width, (int)canvas.Height));
canvas.Arrange(new Rect(new Size((int)canvas.Width, (int)canvas.Height)));
renderBitmap.Render(canvas);
//JpegBitmapEncoder encoder = new JpegBitmapEncoder();
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
using (FileStream file = File.Create(filename))
{
encoder.Save(file);
}
}
但是该方法在windows store app中不起作用(RenderTargetBitmap
没有PngBitmapEncoder
没有5个参数构造函数。所以我的问题是如何从windows商店应用程序中保存画布,因为某种图像文件(jpg,png等)有什么方法可以做到这一点?
答案 0 :(得分:6)
试试这个
using System.Runtime.InteropServices.WindowsRuntime
private async Task CreateSaveBitmapAsync(Canvas canvas)
{
if (canvas != null)
{
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(canvas);
var picker = new FileSavePicker();
picker.FileTypeChoices.Add("JPEG Image", new string[] { ".jpg" });
StorageFile file = await picker.PickSaveFileAsync();
if (file != null)
{
var pixels = await renderTargetBitmap.GetPixelsAsync();
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await
BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
byte[] bytes = pixels.ToArray();
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)canvas.Width, (uint)canvas.Height,
96, 96, bytes);
await encoder.FlushAsync();
}
}
}
}
答案 1 :(得分:2)
我遇到了这个回复,虽然它看起来正是我要找的东西但是没有用。添加错误处理程序显示:
价值不在预期范围内。
最后我发现:
(uint)canvas.Width, (uint)canvas.Height,
均为0.将其替换为:
(uint)canvas.ActualWidth, (uint)canvas.ActualHeight,
它奏效了。不知道为什么它适用于Carlos28而不适合我,但是这个改变对我也有用,所以我感谢Xyriod的回答
答案 2 :(得分:0)
Xyroid,谢谢您的想法和结构。
为了使CreateSaveBitmapAsync()的版本在04/24/20上运行,我必须用以下内容替换您的using
块。
硬编码“ 96”的更改以及用其定义替换“字节”是可选的。
using (Windows.Storage.Streams.IRandomAccessStream stream = await fileToWhichToSave.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
{
Windows.Graphics.Imaging.BitmapEncoder encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.JpegEncoderId, stream);
encoder.SetPixelData(
Windows.Graphics.Imaging.BitmapPixelFormat.Bgra8,
Windows.Graphics.Imaging.BitmapAlphaMode.Ignore,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight,
Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi,
Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi,
pixels.ToArray());
await encoder.FlushAsync();
}