如何在WinUI3中将灰度8位原始像素数据数组(即byte[])显示到Image控件

问题描述 投票:0回答:2

从相机检索原始像素数据数组(byte[]),并将其作为事件通知到主页。
像素格式是这样的:-

  • 灰度8位(即色带= 1)
  • 宽度:612,高度:512 -> 总大小 = 612 * 512 = 313,344 字节

这是我到目前为止的代码,它在图像控制中没有显示任何内容。

// Behind code of Main Page //////////////////////////////////////////////////////

// This event is called when camera image was captured from camera library
private void Camera_ImageCaptured(object? sender, ImageCapturedEventArgs e)
{
    // CameraImage is Image control of the main page
    _ = CameraImage.DispatcherQueue.TryEnqueue(async () =>
    {
        await GetBitmapAsync3(e.ImageBuffer, e.Width, e.Height);
    });
}

// This method is called in UI thread
public async Task GetBitmapAsync3(byte[] data, int width, int height)
{
    WriteableBitmap newImage = new WriteableBitmap(width, height);
    using var stream = newImage.PixelBuffer.AsStream();
    stream.Write(data);
    await stream.FlushAsync();
    stream.Close();
    ViewModel.WriteableBitmap = newImage;
}

// parameters from camera library
public class ImageCapturedEventArgs : EventArgs
{
    public ImageCapturedEventArgs( byte[] buffer, int width, int height );

    public int Height { get; set; }
    public int Width { get; set; }
    public byte[] ImageBuffer { get; set; }
}
// View Model ///////////////////////////////////////////////
public partial class MainViewModel : ObservableRecipient
{
    [ObservableProperty]
    public WriteableBitmap writeableBitmap;
    public int ImageWidth{ get; set; }
    public int ImageHeight { get; set; }
    public int ImageSize => ImageWidth * ImageHeight;

    public MainViewModel()
    {
        ImageWidth = 612;
        ImageHeight = 512;

        writeableBitmap = new WriteableBitmap(ImageWidth, ImageHeight);
    }
}

// 主页的XAML ///////////////////////////////////////////// //////

<UserControl.DataContext>
    <viewmodels:MainViewModel />
</UserControl.DataContext>

<Grid x:Name="ContentArea">
    <Image
        x:Name="CameraImage"
        Grid.Row="0"
        Grid.Column="0"
        Width="612"
        Height="512"
        Source="{Binding WriteableBitmap}" />
</Grid>

我用上面的代码尝试了它,但它在主页中没有显示任何内容...... 有人帮助我吗?

c# bitmap winui-3 winui
2个回答
0
投票

我不确定

Microsoft.UI.Xaml.Media.Imaging.WriteableBitmap
是否支持每个像素1字节数据。

你可以尝试下一个吗?

public async Task GetBitmapAsync3(byte[] data, int width, int height)
{
    byte[] outputData= new byte[width * height * 4];
    int inputIndex = 0;
    int outputIndex = 0;
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            byte value = data[inputIndex++];
            outputData[outputIndex++] = value;
            outputData[outputIndex++] = value;
            outputData[outputIndex++] = value;
            outputData[outputIndex++] = 255;
        }
    }


    WriteableBitmap newImage = new WriteableBitmap(width, height);
    using var stream = newImage.PixelBuffer.AsStream();
    await stream.WriteAsync(outputData);
    await stream.FlushAsync();
    stream.Close();
    ViewModel.WriteableBitmap = newImage;
}

0
投票

您可以使用this库将字节数组解释为位图数据(免责声明:我是作者)。

使用与技术无关的核心包将数组视为 8 位灰度位图:

using KGySoft.Drawing.Imaging;

// ...

// interpreting the byte array as a grayscale bitmap
var myArrayBackedBitmap = BitmapDataFactory.CreateBitmapData(myByteArray,
   new Size(612, 512),
   stride: 612,
   pixelFormat: KnownPixelFormat.Format8bppGrayScale);

// now you can use you can Get/Set pixels, draw other images into your bitmap, etc.

如果您使用 WinUI 3 特定软件包,您可以简单地将托管位图转换为 WinUI 3

WriteableBitmap
:

var myWinUI3Bitmap = await myArrayBackedBitmap.ToWriteableBitmapAsync();

性能考虑:

请注意,

ToWriteableBitmap
始终创建一个新的
WriteableBitmap
实例,这可能会影响性能,因为它既不是一次性的也不是托管的(与WinUI中的几乎所有内容一样,它是一个“远程”COM对象)。重用单个
WriteableBitmap
实例可能会更好:


// A field allocated once
private WriteableBitmap _renderingTarget;

// [...]

// instead of ToWriteableBitmap, just draw the grayscale bitmap always into the same bitmap.
using (var targetBitmapData = _renderingTarget.GetReadWriteBitmapData())
    await myArrayBackedBitmap.DrawIntoAsync(_renderingTarget);

// Here, after the end using block the target WriteableBitmap is invalidated
// so the possible bindings can refresh themselves

也请随意查看 this 库的 WinUI 特定示例。

© www.soinside.com 2019 - 2024. All rights reserved.