WritableBitmap处理单通道16位无压缩DNG的PixelFormat适配问题
解决方案与WritableBitmap使用说明
问题根源
你遇到的异常是因为当前固定使用的PixelFormats.Rgb24是3通道8位格式,和目标DNG的单通道16位(SamplesPerPixel=1,BitsPerSample=16)数据完全不匹配,导致WritePixels无法正确解析缓冲区数据。
正确的PixelFormat选择
针对这种单通道16位的灰度图像,应该使用PixelFormats.Gray16格式——这是WPF专门为单通道16位灰度数据提供的像素格式,完全匹配你的DNG参数。
代码修改步骤
动态获取图像参数并选择对应PixelFormat
在处理无压缩图像时,先读取SamplesPerPixel和BitsPerSample标签,根据参数动态匹配格式:ElseIf cpr = CompressionValues.Uncompressed Then Dim iWidth As Integer = .SourceIFD.GetEntryValueIFD(TagIDsTIFF.ImageWidth) Dim iHeight As Integer = .SourceIFD.GetEntryValueIFD(TagIDsTIFF.ImageHeight) Dim samplesPerPixel As Integer = .SourceIFD.GetEntryValueIFD(TagIDsTIFF.SamplesPerPixel) Dim bitsPerSample As Integer = .SourceIFD.GetEntryValueIFD(TagIDsTIFF.BitsPerSample) Dim resolution As Double = 96.0 If .SourceIFD.ContainsKey(TagIDsTIFF.XResolution) Then resolution = .SourceIFD.GetEntryValueIFD(TagIDsTIFF.XResolution) ' 根据图像参数选择匹配的PixelFormat Dim targetFormat As PixelFormat = PixelFormats.Default Select Case samplesPerPixel Case 1 targetFormat = If(bitsPerSample = 8, PixelFormats.Gray8, PixelFormats.Gray16) Case 3 targetFormat = If(bitsPerSample = 8, PixelFormats.Rgb24, PixelFormats.Rgb48) End Select ' 计算符合WPF要求的Stride(每行字节数,需4字节对齐) Dim bytesPerPixel As Integer = bitsPerSample * samplesPerPixel \ 8 Dim stride As Integer = (iWidth * bytesPerPixel + 3) \ 4 * 4 Me.MainImage = GetUncompressedBitmapImage(.MainImageBuffer, iWidth, iHeight, resolution, stride, targetFormat) End If修改GetUncompressedBitmapImage函数
接收动态传入的PixelFormat,替换固定的Rgb24:Function GetUncompressedBitmapImage(buffer As Byte(), iWidth As Integer, iHeight As Integer, resolution As Double, stride As Integer, pixelFormat As PixelFormat) As BitmapSource Dim wrImage As New WriteableBitmap(iWidth, iHeight, resolution, resolution, pixelFormat, Nothing) wrImage.WritePixels(New Int32Rect(0, 0, iWidth, iHeight), buffer, stride, 0) Return wrImage End Function
WritableBitmap核心使用注意事项
- PixelFormat严格匹配:必须和图像数据的通道数、位深度完全对应,比如:
- 单通道8位→Gray8,单通道16位→Gray16
- 3通道8位→Rgb24,3通道16位→Rgb48
- Stride必须满足对齐要求:每行像素的字节数必须是4的倍数,通用计算公式为:
stride = ((宽度 × 总位深度) + 31) // 32 × 4,或简化为(宽度 × 每个像素字节数 + 3) // 4 × 4 - 缓冲区大小匹配:缓冲区总字节数必须等于
stride × 图像高度,否则WritePixels会抛出范围异常
内容的提问来源于stack exchange,提问作者Mr.CQ
相关产品推荐
相关产品推荐

