在图像文件中保存以编程方式创建的 UIElement 的任意方法
本文关键字:创建 UIElement 任意 方法 方式 编程 文件 图像 保存 | 更新日期: 2023-09-27 17:56:53
我正在尝试在Windows Phone 8.1(C#)应用程序中保存以编程方式在JPG/PNG/BMP图像中创建的UIElement。
我正在使用使用RenderAsync()方法的RenderTargetBitmap类,但它仅适用于在XAML代码中创建的UI元素。当我在直接用 C# 创建的 UI 元素上使用它时,我有以下异常:"System.ArgumentException (值不在预期范围内。
我做错了什么,或者这个类不允许呈现以编程方式创建的 UIElement?有没有办法在Windows Phone 8.1上做到这一点?谢谢!
这是我使用的代码:
private static async void RenderText(string text, int width, int height, int fontsize, string imagename)
{
RenderTargetBitmap b = new RenderTargetBitmap();
var canvas = new Grid();
canvas.Width = width;
canvas.Height = height;
var background = new Canvas();
background.Height = width;
background.Width = height;
SolidColorBrush backColor = new SolidColorBrush(Colors.Red);
background.Background = backColor;
var textBlock = new TextBlock();
textBlock.Text = text;
textBlock.FontWeight = FontWeights.Bold;
textBlock.TextAlignment = TextAlignment.Left;
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.VerticalAlignment = VerticalAlignment.Stretch;
textBlock.Margin = new Thickness(35);
//textBlock.Width = b.PixelWidth - textBlock.Margin.Left * 2;
textBlock.TextWrapping = TextWrapping.Wrap;
textBlock.Foreground = new SolidColorBrush(Colors.White); //color of the text on the Tile
textBlock.FontSize = fontsize;
canvas.Children.Add(textBlock);
await b.RenderAsync(background);
await b.RenderAsync(canvas);
// Get the pixels
var pixelBuffer = await b.GetPixelsAsync();
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name DataFolder.
var dataFolder = await local.CreateFolderAsync("DataFolder",
CreationCollisionOption.OpenIfExists);
StorageFile file = await dataFolder.CreateFileAsync(imagename, CreationCollisionOption.ReplaceExisting);
// Encode the image to the selected file on disk
using (var fileStream = await file.OpenStreamForWriteAsync())
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, fileStream.AsRandomAccessStream());
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Ignore,
(uint)b.PixelWidth,
(uint)b.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
}
它不仅适用于在 XAML 中创建的元素,还适用于这些元素(如 MSDN 所说)VisualTree
:
将
UIElement
可视化树的快照呈现到图像源。
因此,例如,如果您将元素添加到当前主页,您的方法将起作用:
LayoutRoot.Children.Add(canvas);
使用
代码创建 UIElemet 高度和宽度值时,它们将为 0。如果您希望图像具有特定的分辨率,请尝试为UIElement分配相同的高度和宽度。下面显示的代码对我来说效果很好。
public static void SaveElementAsJPG(FrameworkElement element, string ImageName)
{
WriteableBitmap wBitmap = new WriteableBitmap(element, null);
using (MemoryStream stream = new MemoryStream())
{
wBitmap.SaveJpeg(stream, (int)element.ActualWidth, (int)element.ActualHeight, 0, 100);
wBitmap = null;
//Use can either save the file to isolated storage or media library.
//Creates file in Isolated Storage.
using (var local = new IsolatedStorageFileStream(ImageName, FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication()))
{
local.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
}
//Creates file in Media Library.
var lib = new MediaLibrary();
var picture = lib.SavePicture(ImageName, stream.GetBuffer());
}
}