jpegtran.exe无法正确旋转图像

时间:2013-01-30 20:13:45

标签: c++ jpeg libjpeg

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

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

testimg.jpg:before test_output1.jpg:after

正如您所看到的那样,它会旋转图像,但会将其剪切,并且无法正确放置。包中附带的usage.txt文件并不完全是最新的,因为我必须使用-outfile开关而不是它所说的:

  

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

     
      
  • jpegtran [开关] [inputfile]> outputfile
  •   
     

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

     
      
  • jpegtran [switches] inputfile outputfile
  •   
     

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

     

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

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

有关这些内容的更多详细信息,请参阅前面关于cjpeg的讨论   开关。如果您没有指定这些开关,那么您将得到一个简单的   baseline-JPEG输出文件。质量设定等等   由输入文件确定。

     

通过给出其中一个,可以无损地转换图像   开关:

     
      
  • -flip horizo​​ntal水平镜像(左 - 右)。
  •   
  • -flip vertical垂直镜像(上下)。
  •   
  • -rotate 90将图像顺时针旋转90度。
  •   
  • -rotate 180将图像旋转180度。
  •   
  • -rotate 270将图像顺时针旋转270度(或90 ccw)。
  •   
  • -transpose Transpose image(跨越UL-to-LR轴)。
  •   
  • -transverse横向移调(跨越UR-to-LL轴)。
  •   

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

test_output2.jpg:after another rotate 180

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

另外,我在更大的.jpg文件上尝试了它,导致了相同的问题,但输出的文件大小小了18KB。我想这个问题与此有关。


编辑 - 我也发现了这个似乎描述问题的模糊:

  转换奇数尺寸图像时,

jpegtran的默认行为是   旨在保持精确的可逆性和数学一致性   转型集。如上所述,转置能够翻转   整个图像区域。水平镜像会留下任何部分iMCU   右边的列未触及,但能够翻转所有行   图片。类似地,垂直镜像会留下任何部分iMCU行   在底部边缘未触及,但能够翻转所有列。该   其他变换可以构建为转置和翻转的序列   操作;为了保持一致性,他们定义了对边缘像素的操作   与相应的最终结果相同   转置和翻转序列。

-trim开关可以正常工作,如果你可以调用它,并修剪掉杂乱无章的数据,但图像更小,数据丢失。

test_output5.jpg:trimmed output

添加-perfect开关可能会阻止上述操作发生,导致:transformation is not perfect输出而没有图像。

因此无法无损旋转.jpg吗?我自己可以通过简单地将边缘线移动到正确的位置来进行绘画并重建原始图像。有没有办法在libjpeg中执行此操作?

1 个答案:

答案 0 :(得分:1)

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

正如你已经发现解决这个问题的方法是让宽度和高度可以被16整除。你会发现来自摄像机的图像会有这个属性。