我正在尝试编写一个程序(在java中的概率),无需先解码就可以无损地连接多个jpeg.
我以为我会开始简单,尝试使用十六进制编辑器追加相同大小的2个jpegs,使用相同的设置压缩.
首先,我提取jpeg B的图像数据并将其附加到jpeg A.通过修改标题中指定的尺寸,我得到一个新的可识别图片(y轴上附加的jpeg A + jpeg B),可以进行显示.然而,尽管来自jpeg B的图像数据清晰可辨,但它似乎丢失了大量的颜色信息并且显然是不正确的.
所以我的问题是我错过了哪些步骤?我不认为我需要更改任何其他维度特定的标题值,所以也许我需要霍夫曼解码来自两个jpeg的图像数据,然后将它们附加在一起,然后重新编码该批次?
我花了一些时间阅读jpeg规格和标题等,但说实话,我已经超出了我的深度,可以用指针或两个指针!
非常感谢您的帮助.
感谢所有的建议.是的,这绝对是可能的,我应该在我原来的问题中提到jpegtran.我基本上试图复制jpegtran功能的这个方面,但在我自己的程序中使用它.我想我应该看一下jpegtran源代码,但我对C一无所知,而且对一般的编程知之甚少,所以逆向工程源代码说起来容易做起来难!
CDR*_*CDR 19
这是非常可行的.我在很多谷歌地图图片上做了它,加入这些图块并形成一张海报大小的图像.有一个名为JPEG Tools的Unix软件包正是为了做到这一点.该程序称为jpegjoin.纯C源代码,提供Windows二进制文件.在编译时,它会创建一个命令行应用程序,该应用程序在运行时会在许多其他事物中连续丢失两个jpeg图像.它不会对任何图像进行解压缩,只需将压缩数据合并在一起并相应地修复标头.我用它来合并100个图像来创建50个条带,然后再次合并这些条带以创建一个大图像.
有关更多信息,请访问http://en.wikipedia.org/wiki/Lossy_compression#Lossless_editing
源代码
可以在此处找到基础jpegtran库的源代码.模仿jpegjoin的示例脚本就在这里.
好吧,我找出了哪里出错了。
1)图像扫描数据以字节保存,但实际重要信息被编码为可变长度位串。这意味着实际图像数据的结尾不一定落在字节边界上。当 jpeg 编码器需要填充位数以形成字节边界时,它只需添加一系列 1。
2)实际像素信息的存储方式有点太复杂(至少对我来说)难以解释,但基本上所有内容都在 MCU、最小编码单元或其他内容中进行编码。这些尺寸根据色度子采样而变化,水平和垂直尺寸为 8 或 16 像素。对于每个 MCU,都有直流和交流部分组成亮度 Y 或色度 Cb 和 Cr 的单个分量。问题在于,直流分量存储为与先前 MCU 的相关直流值相关的值。因此,当我添加 jpg B 中的新图像数据时,它存储了与 0 相关的 DC 值(因为之前没有 MCU),但它需要考虑 jpg A 中最后一个 MCU 的最终 DC 值。 (希望这是有道理的)。
解决方案:
您需要对图像数据进行初始解码(霍夫曼 + 游程长度),以准确找出图像数据结束的位置,然后去除尾随的 1。您还需要适当更改第二个 jpg 中的初始 DC 值。然后,您需要重新编码适当的位,添加 1 以适应字节边界,等等。
如果你想在x轴上追加,那就有点复杂了。您必须重新排列 MCU,以便它们按正确的顺序进行扫描。Jpg从左到右扫描,然后从上到下扫描,然后适当调整DC值。
到目前为止,我只在单个 MCU jpg 上进行了测试,但理论上它也应该适用于更大的 MCU jpg。
顺便说一句,我之所以能解决这个问题,要感谢这个优秀的 jpg 相关资源/博客的所有者