在 UWP 应用程序中创建动态个人资料图像

Create dynamic profile image in UWP app

我想在我的应用程序中显示用户的个人资料图片。如果数据源中没有可用图像,我想生成 Microsoft 使用的那些动态图像(包含人名的首字母)。

这在 UWP 中可行吗?我发现样本产生了来自 Windows.Graphics.Imaging 命名空间的类型,但它们正在操纵现有图像而不是创建新图像。

RenderTargetBitmap 可以选择将您的 UI 元素呈现为图像,这几乎可以匹配您正在寻找的图像格式,几乎不需要摆弄。下面是从网格渲染图像的方法。

public static async Task<IRandomAccessStream> RenderToRandomAccessStream(this UIElement element)
{
    RenderTargetBitmap rtb = new RenderTargetBitmap();
    await rtb.RenderAsync(element);

    var pixelBuffer = await rtb.GetPixelsAsync();
    var pixels = pixelBuffer.ToArray();

    // Useful for rendering in the correct DPI
    var displayInformation = DisplayInformation.GetForCurrentView();

    var stream = new InMemoryRandomAccessStream();
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
    encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                         BitmapAlphaMode.Premultiplied,
                         (uint)rtb.PixelWidth,
                         (uint)rtb.PixelHeight,
                         displayInformation.RawDpiX,
                         displayInformation.RawDpiY,
                         pixels);

    await encoder.FlushAsync();
    stream.Seek(0);

    return stream;
}

取自Render XAML to image, Blur app UI, or how to enable awesome user experiences in your UWP app

但是这里有一个问题。 RenderTargetBitmap.RenderAsync(UIElement Reference) 将仅呈现附加到 VisualTree 的元素。也就是说,它只能将 UIElement 转换为 Grid,前提是它存在于视图中。 (相信我,将可见性设置为折叠是行不通的)。

所以我最后做的是将网格 Width/Height 设置为 50,但图像 Width/Height 设置为 60。

查看我的XAML

<Grid x:Name="LayoutRoot" VerticalAlignment="Center">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid Width="50" Height="50" Visibility="Visible" Name="GRDData" Background="LightBlue">
        <TextBlock Name="tbModded" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
    <Image Width="60" Height="60" x:Name="bgImage" Margin="10,0"/>
    <TextBlock Grid.Column="1" Margin="10,0">
        <Run x:Name="FN" />
        <Run x:Name="LN" />
    </TextBlock>
</Grid>

现在这是我的代码。只是为了显示元素在后端,我将网格背景设置为红色而不是蓝色,就像 xaml.

中那样
private async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    string FirstName = "Test data";
    FN.Text = FirstName;
    string LastName = "Data Item";
    LN.Text = LastName;
    string ModdedString = FirstName.Substring(0, 1) + LastName.Substring(0, 1);
    tbModded.Text = ModdedString;
    GRDData.Background = new SolidColorBrush(Colors.Red);
    IRandomAccessStream stream = await RenderToRandomAccessStream(GRDData);
    BitmapImage image = new BitmapImage();
    image.SetSource(stream);
    bgImage.Source = image;
}

结束输出