You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP C#保存视频帧为16位JPEG XR格式的问题求助

解决16位JPEG XR编码错误的方案

问题根源

你当前的代码错误在于:WriteableBitmap加载的视频帧是8位BGRA格式(每个像素4字节),但当你将BitmapPixelFormat改为Rgba16时,传入的像素数据仍然是8位的字节数组——16位格式每个像素需要8字节(RGBA各2字节),字节数不匹配直接导致编码器报错。

方案一:转换8位像素数据为16位格式

手动将Bgra8的像素数据扩展为Bgra16格式,再传给编码器:

// 获取8位像素数据(原代码不变)
const int BytesPerPixel8 = 4;
Stream stream = writableBitmap.PixelBuffer.AsStream();
byte[] pixels8 = new byte[(int)frameWidth * (int)frameHeight * BytesPerPixel8];
await stream.ReadAsync(pixels8, 0, pixels8.Length);

// 转换为16位Bgra格式
const int BytesPerPixel16 = 8;
byte[] pixels16 = new byte[(int)frameWidth * (int)frameHeight * BytesPerPixel16];
for (int i = 0; i < pixels8.Length; i += BytesPerPixel8)
{
    // 每个8位通道扩展为16位(0-255 → 0-65535)
    ushort blue = (ushort)(pixels8[i] * 257);
    ushort green = (ushort)(pixels8[i+1] * 257);
    ushort red = (ushort)(pixels8[i+2] * 257);
    ushort alpha = (ushort)(pixels8[i+3] * 257);

    // 写入16位数据(小端字节序)
    Buffer.BlockCopy(BitConverter.GetBytes(blue), 0, pixels16, i*2, 2);
    Buffer.BlockCopy(BitConverter.GetBytes(green), 0, pixels16, i*2+2, 2);
    Buffer.BlockCopy(BitConverter.GetBytes(red), 0, pixels16, i*2+4, 2);
    Buffer.BlockCopy(BitConverter.GetBytes(alpha), 0, pixels16, i*2+6, 2);
}

// 编码16位JXR
using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegXREncoderId, writeStream);
    encoder.SetPixelData(
        BitmapPixelFormat.Bgra16, // 使用匹配的16位格式
        BitmapAlphaMode.Premultiplied,
        (uint)writableBitmap.PixelWidth,
        (uint)writableBitmap.PixelHeight,
        96.0,
        96.0,
        pixels16);
    await encoder.FlushAsync();
}

方案二:用SoftwareBitmap直接处理16位格式(更可靠)

跳过WriteableBitmap,用SoftwareBitmap直接转换图像格式,避免手动操作像素数组:

// 获取视频帧流后,先解码为SoftwareBitmap
var decoder = await BitmapDecoder.CreateAsync(imageStream);
var softwareBitmap8 = await decoder.GetSoftwareBitmapAsync();

// 转换为16位BGRA格式
var softwareBitmap16 = SoftwareBitmap.Convert(softwareBitmap8, BitmapPixelFormat.Bgra16, BitmapAlphaMode.Premultiplied);

// 编码保存
using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite))
{
    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegXREncoderId, writeStream);
    encoder.SetSoftwareBitmap(softwareBitmap16);
    await encoder.FlushAsync();
}

注意事项

  • JXR编码器支持的16位格式包括Bgra16和Rgba16,确保SetPixelData或SetSoftwareBitmap的格式与编码器要求匹配;
  • 如果不需要Alpha通道,可以使用Rgb48格式(每个像素6字节),进一步减小文件体积。

内容的提问来源于stack exchange,提问作者Zemax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:40:17