Ghostscript中使用image函数出现rangecheck错误的原因排查
PostScript 'image'函数显示JPEG图片触发/rangecheck错误的原因及修复
问题重现
你尝试用PostScript的image函数显示Logo,将JPEG转成十六进制内联到代码中,但运行时触发/rangecheck in --image--错误,代码如下:
%!PS-Adobe-3.0 %%LanguageLevel: 3 %%Pages: 1 %%BoundingBox: 0 0 600 800 %%EndComments %%Page: 1 1 gsave % Position and scale 100 300 translate 200 150 scale << /ImageType 1 /Width 508 /Height 382 /BitsPerComponent 8 /ColorSpace [/DeviceRGB] /Decode [0 1 0 1 0 1] /ImageMatrix [508 0 0 -382 0 382] /DataSource currentfile /ASCIIHexDecode filter /DCTDecode filter >> image
代码后跟随由xxd -p WChLogo_rgb.jpg | tr -d '\n' > WChLogo.hex生成的十六进制JPEG数据(以>结尾)。
核心错误原因
- 数据格式不匹配:
image函数(ImageType 1)默认要求未压缩的原始像素数据,但你提供的是JPEG压缩格式的数据。虽然/DCTDecode可以解码JPEG,但当前参数组合下,image无法正确解析压缩数据流的长度,导致数据量与预期的原始像素尺寸不匹配,触发rangecheck。 - 参数冗余/冲突:
/ColorSpace [/DeviceRGB]写法多余,直接写/DeviceRGB即可。ImageMatrix的设置与外部的translate+scale叠加,可能导致坐标计算异常。/Decode数组对JPEG数据无效,因为DCTDecode已经处理了颜色范围映射。
- 尺寸不匹配风险:如果代码中写的
/Width//Height与JPEG真实尺寸不一致,也会触发rangecheck。
修复方案
方案1:改用未压缩原始RGB数据
将JPEG转成未压缩的RGB原始数据,再转成十六进制,让image直接读取:
- 转换原始RGB数据:
convert WChLogo_rgb.jpg -depth 8 rgb:- | xxd -p | tr -d '\n' > WChLogo_raw.hex - 修改PostScript代码,去掉
/DCTDecode filter:%!PS-Adobe-3.0 %%LanguageLevel: 3 %%Pages: 1 %%BoundingBox: 0 0 600 800 %%EndComments %%Page: 1 1 gsave 100 300 translate 200 150 scale << /ImageType 1 /Width 508 /Height 382 /BitsPerComponent 8 /ColorSpace /DeviceRGB /ImageMatrix [1 0 0 -1 0 382] /DataSource currentfile /ASCIIHexDecode filter >> image % 这里粘贴WChLogo_raw.hex的内容,以>结尾
方案2:调整代码支持JPEG压缩数据
如果要保留JPEG压缩格式,调整参数让image配合/DCTDecode正常工作:
- 先确认JPEG真实尺寸:
确保代码中identify WChLogo_rgb.jpg/Width和/Height与输出的尺寸完全一致。 - 修改PostScript代码:
%!PS-Adobe-3.0 %%LanguageLevel: 3 %%Pages: 1 %%BoundingBox: 0 0 600 800 %%EndComments %%Page: 1 1 gsave 100 300 translate 200 150 scale << /ImageType 1 /Width 508 % 替换为JPEG真实宽度 /Height 382 % 替换为JPEG真实高度 /BitsPerComponent 8 /ColorSpace /DeviceRGB /ImageMatrix [1 0 0 -1 0 382] % 仅处理垂直翻转,缩放交给外部scale /DataSource currentfile /ASCIIHexDecode filter /DCTDecode filter >> image % 这里粘贴原十六进制JPEG数据,以>结尾
关键注意事项
- 十六进制数据必须以
>结尾,否则ASCIIHexDecode会报错。 - 确保
/BitsPerComponent与JPEG的位深度一致(通常是8)。 - 避免
ImageMatrix与外部translate/scale的叠加冲突,尽量用其中一种方式控制位置和尺寸。
内容的提问来源于stack exchange,提问作者Bill Lee
相关产品推荐
相关产品推荐

