我想为使用C#for WinRT的孩子制作一个简单的绘图应用程序。用户可以选择一张图片并画一点。但是如何保存图像(与背景一起)?没有用背景保存图像的功能。
答案 0 :(得分:2)
我尝试使用你的库将Canvas渲染成图像文件,但我得到了这个错误运行时:“找不到组件。(HRESULT异常:0x88982F50)”。代码如下所示:
//SAVE
private async void saveButton_Click(object sender, RoutedEventArgs e)
{
await SaveToFile();
}
public async Task SaveToFile()
{
var wb = new WriteableBitmap(1, 1);
await wb.Render(canvas);
Windows.Storage.Pickers.FileSavePicker save = new Windows.Storage.Pickers.FileSavePicker();
save.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
save.DefaultFileExtension = ".jpg";
save.FileTypeChoices.Add("JPG", new string[] { ".jpg" });
StorageFile filesave = await save.PickSaveFileAsync();
await wb.SaveToFile(filesave, Guid.NewGuid());
}
答案 1 :(得分:1)
如果您将图像绘制到WriteableBitmap
WinRT XAML Toolkit中,您可以使用一些扩展方法来保存图像:
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.UI.Xaml.Media.Imaging;
namespace WinRTXamlToolkit.Imaging
{
/// <summary>
/// Extension methods used for saving a WriteableBitmap to a file.
/// </summary>
public static class WriteableBitmapSaveExtensions
{
/// <summary>
/// Saves the WriteableBitmap to a png file with a unique file name.
/// </summary>
/// <param name="writeableBitmap">The writeable bitmap.</param>
/// <returns>The file the bitmap was saved to.</returns>
public static async Task<StorageFile> SaveToFile(
this WriteableBitmap writeableBitmap)
{
return await writeableBitmap.SaveToFile(
KnownFolders.PicturesLibrary,
string.Format(
"{0}_{1}.png",
DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
Guid.NewGuid()),
CreationCollisionOption.GenerateUniqueName);
}
/// <summary>
/// Saves the WriteableBitmap to a png file in the given folder with a unique file name.
/// </summary>
/// <param name="writeableBitmap">The writeable bitmap.</param>
/// <param name="storageFolder">The storage folder.</param>
/// <returns>The file the bitmap was saved to.</returns>
public static async Task<StorageFile> SaveToFile(
this WriteableBitmap writeableBitmap,
StorageFolder storageFolder)
{
return await writeableBitmap.SaveToFile(
storageFolder,
string.Format(
"{0}_{1}.png",
DateTime.Now.ToString("yyyyMMdd_HHmmss_fff"),
Guid.NewGuid()),
CreationCollisionOption.GenerateUniqueName);
}
/// <summary>
/// Saves the WriteableBitmap to a file in the given folder with the given file name.
/// </summary>
/// <param name="writeableBitmap">The writeable bitmap.</param>
/// <param name="storageFolder">The storage folder.</param>
/// <param name="fileName">Name of the file.</param>
/// <param name="options">
/// The enum value that determines how responds if the fileName is the same
/// as the name of an existing file in the current folder. Defaults to ReplaceExisting.
/// </param>
/// <returns></returns>
public static async Task<StorageFile> SaveToFile(
this WriteableBitmap writeableBitmap,
StorageFolder storageFolder,
string fileName,
CreationCollisionOption options = CreationCollisionOption.ReplaceExisting)
{
StorageFile outputFile =
await storageFolder.CreateFileAsync(
fileName,
options);
Guid encoderId;
var ext = Path.GetExtension(fileName);
if (new[] { ".bmp", ".dib" }.Contains(ext))
{
encoderId = BitmapEncoder.BmpEncoderId;
}
else if (new[] { ".tiff", ".tif" }.Contains(ext))
{
encoderId = BitmapEncoder.TiffEncoderId;
}
else if (new[] { ".gif" }.Contains(ext))
{
encoderId = BitmapEncoder.TiffEncoderId;
}
else if (new[] { ".jpg", ".jpeg", ".jpe", ".jfif", ".jif" }.Contains(ext))
{
encoderId = BitmapEncoder.TiffEncoderId;
}
else if (new[] { ".hdp", ".jxr", ".wdp" }.Contains(ext))
{
encoderId = BitmapEncoder.JpegXREncoderId;
}
else //if (new [] {".png"}.Contains(ext))
{
encoderId = BitmapEncoder.PngEncoderId;
}
await writeableBitmap.SaveToFile(outputFile, encoderId);
return outputFile;
}
/// <summary>
/// Saves the WriteableBitmap to the given file with the specified BitmapEncoder ID.
/// </summary>
/// <param name="writeableBitmap">The writeable bitmap.</param>
/// <param name="outputFile">The output file.</param>
/// <param name="encoderId">The encoder id.</param>
/// <returns></returns>
public static async Task SaveToFile(
this WriteableBitmap writeableBitmap,
StorageFile outputFile,
Guid encoderId)
{
Stream stream = writeableBitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[(uint)stream.Length];
await stream.ReadAsync(pixels, 0, pixels.Length);
using (var writeStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(encoderId, writeStream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)writeableBitmap.PixelWidth,
(uint)writeableBitmap.PixelHeight,
96,
96,
pixels);
await encoder.FlushAsync();
using (var outputStream = writeStream.GetOutputStreamAt(0))
{
await outputStream.FlushAsync();
}
}
}
}
}
该工具包在WinRTXamlToolkit.Composition
库中也有一些方法,可以使用Direct2D将使用XAML UI布局的文本和形状渲染到图像中,但它仍处于开发的早期阶段,不支持渲染图像控件或背景呢。