如何在JPEG中添加文本并将画质损失降至最低?
关于JPEG添加文本时的画质与体积控制问题
我正在使用fswebcam工具,它可输出原始帧与处理后帧,能为图片添加文本(如时间戳),但目前遇到画质问题,该问题并非直接源于工具本身,而是涉及JPEG处理的通用原理。
相机输出的原始图像为JPEG格式,我无法控制其画质。例如相机返回画质为76时,未做特殊配置的fswebcam会输出画质100的图像,导致文件体积暴涨。虽然可通过fswebcam参数设置画质,但需先通过magick identify获取原始文件的画质,且每次拍摄都需检查,因为相机可能自行选择不同的画质等级。
我了解到用更高画质重打包JPEG无意义,但不确定添加文本后以相同画质重打包是否会降低画质。实际观察发现,即使以相同画质重打包也会产生伪影。因此,为在保留画质的同时在图片底部添加文本,我尝试了两种思路:
- (a) 保留相机原始JPEG不变,通过其他方式添加文本——尝试在SOI与EOI之间插入图像但无效,也曾考虑用透明PNG叠加JPEG(如CSS实现),但过于繁琐;
- (b) 寻找可靠方法,在嵌入文本后重打包原始JPEG,使未被文本覆盖区域的伪影最少或无伪影,比如将原始JPEG解压为24位BMP,添加文本后再重新打包。
最终目标有两个:
- 添加文本后JPEG画质与原文件一致;
- 文件体积与原文件相近。
恳请提供有依据的建议或经验,感谢!
更新
特别感谢Martin,我现在使用以下脚本:
jpegtran -crop 1920x1144+0+0 /tmp/a1.jpg > a11.jpg magick -size 1920x64 pattern:gray0 -colors 3 -font /usr/share/fonts/ttf-dejavu/DejaVuSans.ttf -gravity SouthWest -background red -fill white -pointsize 28 -annotate +0+0 '123456789012345' -annotate +0+28 'CAM-11' -gravity SouthEast -annotate +0+0 'Webcam @ bus:0.1.1.1.1.1' -annotate +0+28 "$(date)" -gravity South -annotate +0+0 "Qo: 76" -annotate +0+28 "Qi: 100" -stroke gray -strokewidth 4 -draw "line 0,0 1919,0" -quality 90 result.jpg jpegtran -drop +0+1080 result.jpg -outfile result1.jpg a11.jpg
输入图像画质为90,原始体积4MB,裁剪为a11.jpg后体积为193kB;生成带文本的 footer 画质同样为90,体积24kB。
最后一步拼接图片后,生成文件体积为306kB,而非预期的193+24=217kB。此外,使用命令检查该文件时出现报错:
# magick identify -verbose result1.jpg identify: InsufficientImageDataInFile `result1.jpg' @ error/jpeg.c/ReadJPEGImage/1183.
但该文件可在图片查看器中正常打开。请问这种情况是否正常?问题出在哪里?
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

