我正在尝试以编程方式保存在Windows Phone 8.1(C#)应用程序中的JPG / PNG / BMP图像中创建的UIElement。
我使用RenderAsync()方法使用RenderTargetBitmap类,但它只适用于在XAML代码中创建的UI元素。当我在直接在C#中创建的UI元素上使用它时,我有以下异常:“System.ArgumentException(Value不在预期范围内。)”
我做错了什么或者这个类不允许以编程方式创建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();
}
}
答案 0 :(得分:2)
它不仅适用于在XAML中创建的元素,但具有这些元素(MSDN says)位于VisualTree
中:
将
UIElement
可视树的快照呈现给图像源。
因此,如果您将元素添加到当前页面中,则您的方法将起作用:
LayoutRoot.Children.Add(canvas);
答案 1 :(得分:0)
使用代码创建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());
}
}