【问题标题】:Save canvas from windows store app as image file将 Windows 商店应用程序中的画布保存为图像文件
【发布时间】:2020-04-25 06:48:05
【问题描述】:

我正在寻找从 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 商店应用程序中不起作用(RenderTargetBitmap 没有 5 个参数构造函数,PngBitmapEncoder 没有)。所以我的问题是如何将 Windows 商店应用程序中的画布保存为某种图像文件(jpg、png 等)。有什么方法可以做到这一点?

【问题讨论】:

  • @Dick,如果您在 Xaml 代码中放置画布宽度和高度,则无需编写 canvas.ActualWidth 或高度。显示这种类型的异常意味着您没有设置画布的宽度和高度。这就是它询问实际高度或宽度的原因。检查一下。快乐编码,

标签: c# canvas windows-store-apps visual-studio-2013


【解决方案1】:

试试这个

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“Windows.Storage.Streams.IBuffer”不包含“ToArray”的定义,并且没有扩展方法“ToArray”接受“Windows.Storage.Streams.IBuffer”类型的第一个参数可以找到(您是否缺少 using 指令或程序集引用?) C:\... 198 51 PhotoEditor1
  • 如果我的解决方案对您有用,请将答案标记为已接受。这对其他人会有所帮助。
  • 只是要注意这里的人所做的更改是在代码顶部添加 System.Runtime.InteropServices.WindowsRuntime 库!
【解决方案2】:

我看到了这个回复,虽然它看起来正是我要找的东西,但它没有用。添加错误处理程序显示:

值不在预期范围内。

最后我发现:

(uint)canvas.Width, (uint)canvas.Height,

都是0。替换为:

(uint)canvas.ActualWidth, (uint)canvas.ActualHeight,

成功了。不知道为什么它适用于 Carlos28 而不是我,但有了这个改变它也适用于我,所以我感谢 Xyriod 的回答

【讨论】:

    【解决方案3】:

    谢谢你,Xyroid,你的想法和结构。 为了让 CreateSaveBitmapAsync() 版本在 2020 年 4 月 24 日工作,我必须用以下内容替换您的 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();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多