在图像文件中保存以编程方式创建的 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();
        }
    }

在图像文件中保存以编程方式创建的 UIElement 的任意方法

它不仅适用于在 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());
        }
    }