XAML winui3有办法显示8*8大小的像素图像吗

mf98qq94  于 2023-08-01  发布在  其他
关注(0)|答案(1)|浏览(97)

我可以在WPF应用程序中使用这些代码来实现这一点:

<Image x:Name="myImage" RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.ClearTypeHint="Enabled" />

字符串
相应的效果如下https://i.stack.imgur.com/ed5MN.png
但是对于winui3

<Image Source="/Assets/steve.png" />


相应的效果如下,图像被放大许多倍,变得模糊https://i.stack.imgur.com/q20Fv.png
这是原始图像https://i.stack.imgur.com/q4QAb.png
那么有没有办法保持winui3的图像以像素为单位显示呢?
我希望在winui3中的图像可以得到像在wpf中一样的显示效果

omvjsjqw

omvjsjqw1#

有多种方法可以做到这一点,但没有使用XAML。“经典”的方法是使用WinRT的BitmapDecoder类并自定义其工作方式。

方案一

使用此XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Grid.Row="0" Click="Button_Click">click</Button>

    <Image x:Name="img" Grid.Row="1" Width="300" Height="300" />

</Grid>

字符串
这段代码:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    // create a BitmapDecoder
    var file = await StorageFile.GetFileFromPathAsync(@"c:\somepath\q4QAb.png");
    using var stream = await file.OpenStreamForReadAsync();
    using var ras = stream.AsRandomAccessStream();
    var decoder = await BitmapDecoder.CreateAsync(ras);

    // create a bitmap transform.
    // you'll have to call this with width & height corresponding to desired Image's with & height
    var transform = new BitmapTransform();
    transform.InterpolationMode = BitmapInterpolationMode.NearestNeighbor;
    transform.ScaledWidth = (uint)img.Width;
    transform.ScaledHeight = (uint)img.Height;

    // load the bitmap & bitmap source using transform
    using var bmp = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
    var source = new SoftwareBitmapSource();
    await source.SetBitmapAsync(bmp);
    img.Source = source;
}

方案二

下面是另一种方法,使用the Visual Layer(又名:直接组成),不限于UWP,与文件可能说的相反:
使用此XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Grid.Row="0" Click="Button_Click">click</Button>

    <Canvas x:Name="canvas" Grid.Row="1" />

</Grid>


这个按钮处理代码:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // get visual layer's compositor
    var compositor = ElementCompositionPreview.GetElementVisual(canvas).Compositor;

    // create a surface brush, this is where we can use NearestNeighbor interoplation
    var brush = compositor.CreateSurfaceBrush();
    brush.BitmapInterpolationMode = CompositionBitmapInterpolationMode.NearestNeighbor;

    // create a visual
    var imageVisual = compositor.CreateSpriteVisual();
    imageVisual.Brush = brush;

    // load the image
    var image = LoadedImageSurface.StartLoadFromUri(new Uri(@"c:\somepath\q4QAb.png"));
    brush.Surface = image;

    // set the visual size when the image has loaded
    image.LoadCompleted += (s, e) =>
    {
        // choose any size here
        imageVisual.Size = new System.Numerics.Vector2(300, 300);
        image.Dispose();
    };

    // add the visual as a child to canvas
    ElementCompositionPreview.SetElementChildVisual(canvas, imageVisual);
}


注1:在解决方案2的情况下,您不必使用async/await代码。您也可以随时调整imageVisual视觉。没有更多的上下文信息,这是我的首选方式。
注2:所有UI/XAML命名空间 * 必须 * 以Microsoft.UI.Xaml开头,以确保您使用的是WinUI 3而不是UWP。

相关问题