2

我有一个新编译的 libjpeg 版本 9,并尝试在命令行中使用参数运行 jpegtran.exe:

.\jpegtran.exe -rotate 180 -outfile test_output1.jpg testimg.jpg

testimg.jpg: 前test_output1.jpg:后

正如您所看到的,它确实旋转了图像,但它会剪辑它并且它没有正确组合在一起。软件包附带的 usage.txt 文件并不是最新的,因为我必须使用 -outfile 开关而不是它所说的:

jpegtran 使用类似于 cjpeg 或 djpeg 的命令行语法。在类 Unix 系统上,你说:

  • jpegtran [开关] [输入文件] >输出文件

在大多数非 Unix 系统上,您会说:

  • jpegtran [开关] 输入文件输出文件

其中输入和输出文件都是 JPEG 文件。

要指定输出文件中使用的编码 JPEG 表示,jpegtran 接受 cjpeg 识别的开关子集:

  • -optimize 执行熵编码参数的优化。
  • -progressive 创建渐进式 JPEG 文件。
  • -arithmetic 使用算术编码。
  • -restart N 每 N MCU 行或每 N MCU 块发出一个 JPEG 重启标记,如果“B”附加到数字。
  • -scans file 使用指定文本文件中给出的扫描脚本。

有关这些开关的更多详细信息,请参阅之前对 cjpeg 的讨论。如果您没有指定这些开关,您将获得一个普通的基线JPEG 输出文件。质量设置等由输入文件确定。

通过提供以下开关之一,可以无损地转换图像:

  • -水平翻转水平镜像(左右)。
  • -flip vertical 垂直镜像(上下)。
  • -rotate 90 将图像顺时针旋转 90 度。
  • -rotate 180 将图像旋转 180 度。
  • -rotate 270 将图像顺时针旋转 270 度(或 90 ccw)。
  • -transpose 转置图像(跨 UL 到 LR 轴)。
  • -transverse 横向转置(跨 UR 到 LL 轴)。

奇怪的是(或者可能不是),如果我执行,.\jpegtran.exe -rotate 180 -outfile test_output2.jpg test_output1.jpg我会得到原始图像而没有任何剪辑问题。它正在翻转剪裁的部分,但只是没有将其与图像的其余部分对齐。

test_output2.jpg:又旋转180

jpegtran.exe -rotate 90通过执行两次,我得到了相同的结果。

此外,我在一个较大的 .jpg 文件上进行了尝试,这导致了同样的问题,但输出的文件大小小了 18KB。我想这个问题与此有关。


编辑-我还发现了这个似乎描述问题的简介:

jpegtran 在转换奇数大小的图像时的默认行为旨在保持转换集的精确可逆性和数学一致性。如前所述,转置能够翻转整个图像区域。水平镜像使右侧边缘的任何部分 iMCU 列保持不变,但能够翻转图像的所有行。类似地,垂直镜像使底部边缘的任何部分 iMCU 行保持不变,但能够翻转所有列。其他变换可以构建为转置和翻转操作的序列;为了一致性,它们对边缘像素的动作被定义为与相应的转置和翻转序列的最终结果相同。

-trim 开关起作用,如果你可以这样称呼它,并修剪掉杂乱无章的数据,但图像更小并且丢失数据。

test_output5.jpg:修剪输出

添加据称可以阻止上述情况发生的 -perfect 开关会导致:transformation is not perfect输出且没有图像。

那么不可能无损地旋转.jpg吗?我自己可以通过简单地将边缘线移动到正确的位置来进行绘画并重建原始图像。有没有办法在 libjpeg 中做到这一点?

4

1 回答 1

2

无损旋转适用于 JPEG 文件中包含的整个 DCT 块。这些块始终为 8x8 或 16x16 像素(取决于压缩下采样设置)。该文件包含宽度和高度,因此在解码图像时可以丢弃额外的像素,但无法将剪辑从右/下边缘移动到左/上边缘。该软件正在尽其所能解决一个不可能的问题。

正如您所发现的,解决此问题的方法是使宽度和高度可被 16 整除。您会发现,例如来自相机的图像将具有此属性。

于 2013-01-30T21:06:00.313 回答