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

WritableBitmap处理单通道16位无压缩DNG的PixelFormat适配问题

解决方案与WritableBitmap使用说明

问题根源

你遇到的异常是因为当前固定使用的PixelFormats.Rgb24是3通道8位格式,和目标DNG的单通道16位(SamplesPerPixel=1,BitsPerSample=16)数据完全不匹配,导致WritePixels无法正确解析缓冲区数据。

正确的PixelFormat选择

针对这种单通道16位的灰度图像,应该使用PixelFormats.Gray16格式——这是WPF专门为单通道16位灰度数据提供的像素格式,完全匹配你的DNG参数。

代码修改步骤

  1. 动态获取图像参数并选择对应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
    
  2. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:15:31