使用Libtiff .NET写入Linear DNG时出现JPEG尺寸与tile不匹配错误
问题原因及修复方案
代码错误点
报错JPEG dimensions do not match tile的核心原因是设置的DNG标签和实际写入的JPEG数据属性不匹配,具体有3个错误:
- 通道数设置错误:你将
SAMPLESPERPIXEL设为1,但输入的JPG是RGB三通道图像,数值需要改为3 - 缺失
ROWSPERSTRIP标签:你未指定单条带的行数,WriteRawStrip写入整图数据时尺寸校验失败,需要设置为图像的实际高度 - JPEG保存参数不匹配:默认GDI+保存JPEG时采用4:2:0色度子采样,部分DNG解析器要求Linear DNG的Lossy JPEG采用4:4:4全采样,且不能包含多余的APP1等私有分段
修改后的代码
public static void LinearRawDng() { string file = "eva.jpg"; using (Tiff tif = Tiff.Open("eva-linear.dng", "w")) { Image img = Image.FromFile(file); byte[] raster; // 配置JPEG保存参数,使用4:4:4全采样,无多余分段 EncoderParameters encoderParams = new EncoderParameters(2); encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L); encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Sampling, (long)EncoderValue.Sampling444); ImageCodecInfo jpegCodec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid); using (MemoryStream ms = new MemoryStream()) { img.Save(ms, jpegCodec, encoderParams); raster = ms.ToArray(); } tif.SetField(TiffTag.MAKE, "Fitler"); tif.SetField(TiffTag.UNIQUECAMERAMODEL, "Fitler"); tif.SetField(TiffTag.DNGVERSION, "\x1\x4\x0\x0"); tif.SetField(TiffTag.DNGBACKWARDVERSION, "\x1\x4\x0\x0"); tif.SetField(TiffTag.SUBFILETYPE, 0); tif.SetField(TiffTag.PHOTOMETRIC, 34892); tif.SetField(TiffTag.COMPRESSION, 34892); // 修正通道数为3 tif.SetField(TiffTag.SAMPLESPERPIXEL, 3); tif.SetField(TiffTag.BITSPERSAMPLE, 8); tif.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT); tif.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); tif.SetField(TiffTag.IMAGEWIDTH, img.Width); tif.SetField(TiffTag.IMAGELENGTH, img.Height); // 补充行数字段,设置为整图高度 tif.SetField(TiffTag.ROWSPERSTRIP, img.Height); // 补充颜色空间标签,sRGB对应值为1 tif.SetField(TiffTag.COLORSPACE, 1); var result = tif.WriteRawStrip(0, raster, raster.Length); tif.Close(); Console.WriteLine("Finished"); } }
工具替代方案
如果不需要自己写代码,直接用ImageMagick单行命令即可生成符合规范的Lossy JPEG压缩Linear DNG:magick convert eva.jpg -define dng:compression=lossy-jpeg eva-linear.dng
生成后可以直接用dng_validate.exe校验通过。
内容的提问来源于stack exchange,提问作者dimonser
相关产品推荐
相关产品推荐

