如果无损旋转图像,为什么文件大小会改变?


37

我正在寻找无损图像旋转的方法,并偶然遇到了这个问题,这很好地解释了这个问题:

“ Windows Photo Viewer”旋转是否无损?

因此,我创建了一个具有随机像素的256×256 JPEG(Photoshop云滤镜),然后使用Windows Picture Viewer对其进行了旋转。旋转后,文件大小实际上增加了,但仅在第一次旋转时才增加。此后每旋转一次,文件大小就保持不变。我知道它的旋转是无损的,因为我已经多次旋转了它,而没有明显的质量损失,而将257×257的图像旋转了20次变得非常有损。


8
在您的测试中,文件大小增加了多少?
詹姆斯·斯内尔

3
@JamesSnell我知道我应该包括在内。我刚才使用GIMP的差分clounds过滤器所做的一个最初是14,583字节,但在轮换后更改为23,638字节。如果我们仅讨论元数据,则相差9000多个字节,这似乎是很多额外的数据。
oscreatingcretin

4
似乎还有很多其他元数据。我不会很快就假设所有其他数据都是元数据。在我看来,由于元数据引起的大小差异几乎应该是一个常数(在几个字节之内,以表示某些数字的字符串表示形式)。
scottbb '16

4
当提供与问题密切相关的其他信息时,请在问题中而不是在注释中进行编辑。评论是短暂的,可以不时清理。
scottbb '16

2
上载测试图像的原始版本会有所帮助。
CodesInChaos

Answers:


36

这很可能是由熵编码引起的,熵编码是对JPEG数据进行量化以减小其大小之后的JPEG压缩的最后一个无损阶段。

当JPEG图像进行无损旋转时,必须撤消该最终的无损编码层,解压缩后的DCT系数四处乱动,然后再对经过乱码的系数进行熵编码。由于熵编码层的效率取决于每个块内DCT系数的顺序(旋转图像将发生变化),因此旋转图像文件可能比原始图像小或大几个百分点,这不足为奇。

熵编码步骤也可以通过几种不同的方式完成,因此完全相同的JPEG图像的文件大小很有可能会根据进行编码的软件而有所不同。编码器之间的一些潜在差异包括:

  • 与Huffman编码(更简单,标准)相比,选择算术编码(稀有但可能更有效,曾经获得专利);
  • 选择顺序编码(每个8x8像素块一次编码)与逐行编码(所有块的低频分量在较高频率分量之前进行编码,通常稍微更紧凑)的编码顺序;
  • 选择使用标准霍夫曼符号表(更快,更简单,对于非常小的图像可能更有效)与针对每个图像优化的自定义表的选择(对于大图像通常更有效,编码更慢且更复杂);
  • 如果使用自定义霍夫曼表,则不同的编码器可能会为同一图像数据生成不同的表;
  • 编码过程本身的各种低级细节,例如是否以及何时在数据流中包括重启标记,在编码器之间也可能有所不同。

同样,人们通常使用的“ JPEG文件”实际上包含包装在JFIFExif容器中的JPEG压缩图像数据,该图像数据与一个或多个元数据块结合在一起,并引入了其自身的复杂性。即使旋转图像的软件实际上并未对JFIF / Exif元数据进行任何实质性更改,仅重新排列数据也可能会影响文件大小几个字节。

特别是,JFIF / Exif元数据可能包含一个或多个全尺寸图片的缩略图,旋转图片的软件实际上应该重新生成(或无损旋转!)缩略图,以使其与全尺寸图片的新方向匹配。尺寸图片。仅此一项就可以轻松解决观察到的尺寸差异。


4
对于9KB(60%)的差异,我的猜测是缩略图。
BlueRaja-Danny Pflughoeft

JPEG可能太简单了,以至于不值得编码器去做,但是x264之类的视频编码器实际上可以在决定速率与失真权衡时,考虑到入口编码器对接下来要输出的内容进行编码的能力。(即,确定每个替代方案可能花费多少位,并针对有损错误进行权衡)。这称为网格量化。请参见x264的作者(Loren Merritt)关于在H.264中实现网格量化的注释。他从对目标的基本解释开始。
彼得·科德斯

无论如何,JPEG编码器可能已经选择了DCT系数,以便它们可以用熵编码器很好地压缩,因此即使是最佳压缩器也无法使旋转版本变小。(因为以不同的顺序放置它们,可能会使它们的压缩效果不太好。)这对于JPEG几乎肯定是很小的效果,因为每个8x8块都是单独编码的(重置熵编码器AFAIK的状态)。(h.264中的I帧使用帧内预测,​​根据同一帧中的其他块进行预测,从而使其在相同的视觉质量下比JPEG小。)
Peter Cordes

24

我继续进行重复实验,看看是否能弄清楚发生了什么。

程序

我使用默认设置(如下所示)使用GIMP中的“实噪声”滤镜(滤镜>渲染>云>实噪声...)生成了一个256 x 256像素的随机RGB图像:

在此处输入图片说明

结果:

在此处输入图片说明

然后,使用默认设置将图像另存为JPEG:

在此处输入图片说明

然后,我将图像传输到Windows,并通过在文件资源管理器中右键单击该图像并从菜单中选择“ 预览”,使用Windows Photo Viewer打开该图像。然后,我使用底部的按钮旋转了图像,并使用箭头键导航到下一张图像来保存图像。

对于下面的每个测试,我从原始图像的副本开始,然后在保存之前旋转(单击旋转按钮)相应的次数。以下是重新排列的大小(ls -l -r):

                    size in bytes    last-modified date 
                          VVVVV        VVVVV
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 ccw-ccw-ccw-ccw-ccw.jpg

立即观察

  • Windows Photo Viewer(WPV)确实会大大增加大小;在此测试中,增加量约为四倍!
  • 所有新图像都增加到大约相同的大小,但它们并不相同。
  • 当图像旋转360度的倍数时,WPV不会重新编码甚至重新保存图像。(时间戳为11:27,是首次复制文件的时间。)

cmp -l在应具有相同内容的文件上使用,使我们可以查看文件的不同之处。

robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  60  66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  62  64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
 2223  62  63
 2224  71  60
 2226  64  60
 2227  61  64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
 2221  60  61
 2223  63  61
 2224  60  66
 2226  60  61
 2227  60  61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
 2223  62  63
 2224  71  60
 2226  64  65
 2227  61  64

这些文件只有四个字节的不同(实际上是一个时间戳),这意味着WPV每次都在做相同的事情。现在我们只需要弄清楚那是什么。

详细观察

为此,我使用JPEGsnoop来查看图像中到底是什么。

由于输出相当长,因此我已将其链接为要点。以下是差异的摘要:

  • GIMP仅将APP0(JFIF)和COM(注释)段用于元数据。WPV使该APP0段保持不变,但奇怪的是在注释中添加了一个空字节(以便它以空终止)。

  • WPV添加了两个APP1段,分别是Exif和XMP元数据。这些段分别为4286和12726字节。它们在一起几乎占了文件大小的全部增长。

  • GIMP生成渐进式JPEG,而WPV生成基线(非渐进式)JPEG。因此,GIMP的图像有多个扫描段,而WPV图像只有一个。以我的经验,渐进式图像有时会略小。

  • GIMP使用1×1色度二次采样,而WPV使用2×2色度采样。这使我相信WPV不会使用“真实的”无损旋转,除非它能够以某种方式检测到这是黑白图像。

为了解决这些问题,我进行了第二次测试。

程序

我遵循与第一次测试类似的步骤。我使用具有以下设置的RGB噪波滤镜(滤镜>鼻子> RGB鼻子...)创建了一个随机的256×256 RGB图像:

在此处输入图片说明

结果如下:

在此处输入图片说明

我使用以下设置将文件导出为JPEG:

在此处输入图片说明

渐进式已关闭,但子采样仍设置为4:4:4(这是1×1子采样的另一个名称)。质量增加到98。

我复制了图像,然后顺时针旋转了副本。然后复制旋转版本并逆时针旋转该副本,这样我们就可以直接比较原始版本和WPV处理过的副本之间的质量。

结果

-rwxrwx--- 1 root vboxsf 159774 Nov  8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov  8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov  8 16:24 cw-ccw-random.jpg

尽管这次的增加相对而言较小(大约40%),但绝对增加甚至更大-大约62 kB。这表明WMV正在使用效率较低的编码。

我将使用ImageMagick比较两个图像:

robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
  Channel distortion: AE
    red: 0
    green: 0
    blue: 0
    all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020

零个像素不同的原件和循环副本之间。因此,即使WPV没有使用“真正的”无损旋转,它也做得很好。我怀疑我知道发生了什么,并且要解释一下,我将稍微介绍一下JPEG压缩背后的数学原理。

JPEG压缩算法将图像分成8×8像素块。然后,对这些块中的每个块进行离散余弦变换(DCT)。所得的DCT系数将该块描述为不同频率波的总和。然后,该算法“丢弃”高频波中与噪声和非常小的细节相对应的一些信息。解码过程使DCT反向,将存储的波加在一起以返回该块。

无需实际撤消和重做变换就可以旋转DCT“波”(基本上,将所有水平波转换为垂直波,反之亦然)。我认为在WPV中发生的事情是图像实际上已经解码,旋转然后重新编码。在重新编码过程中,由于我们的图像尺寸在两个维度上均为8的倍数,因此每个新块都对应于一个原始块。重要的是,由于每个块都没有高频分量,因此该算法不会丢弃任何信息,并且可以找到“真正的”无损旋转将具有的正确DCT分量。

最后,我将再次查看JPEG文件的组件。结果再次与要点联系在一起。比较两者:

  • WPV图像包含额外的4286 + 2字节的Exif元数据,注释中的1个额外字节和12726 + 2字节的XMP元数据。这是总共17,017字节的其他元数据。这些数据全部用来做什么?我使用值得信赖的十六进制编辑器和相关标准的副本浏览了该文件:

    • Exif元数据的结构类似于TIFF图像,其中包含许多标签(方式更加复杂,但我将跳过它)。Exif段中的大多数字节都包含在两个相同的标签号为标签EA1C(十进制59,932)的标签中。在我能找到的任何地方都没有记录该标签号。这两个标记都包含2060个“未定义”类型的字节,除了前六个(1C EA 00 00 00 08)之外,所有字节均为空字节。我不知道这些标签是什么,为什么有两个标签,为什么每个标签都需要2 kB。

    • XMP元数据实际上是一个完整的带有名称空间和长UUID的嵌入式XML文档,其中仅包含WPV版本字符串(该字符串已在Exif元数据中)。但是,这仅占大约400个字节。该段的其余部分是100个空格的122个重复,后跟换行符。完全浪费的空间超过12,000个字节。

  • 像以前的测试一样,GIMP和WPV都使用相同的DCT量化表。这意味着他们应该计算出完全相同的DCT系数,这就是为什么图像完全相同的原因。我不确定WPV是否恰好使用了相同的量化表,还是从输入中复制了这些表。

  • 与之前的测试不同,这次WPV使用1×1二次采样,因此实际上可能是在检测这是彩色图像(或者至少需要更高的样本才能无损地重新编码图像)。

  • GIMP和WPV使用不同的霍夫曼表(熵编码步骤的一部分)。WPV的表大了总共279个字节,在一种情况下,包含7倍的代码。

    查看JPEGsnoop的统计数据,我们可以发现其中一些代码很少使用。例如,在ID: 1, Class: AC表中,在定义的119个16位代码中,实际上仅使用了23个。总体而言,在WPV版本中,实际扫描段要大28.5%。

摘要

  • WPV可能没有进行“真实的”无损旋转,但是旋转实际上似乎是无损的。

  • 额外的大小部分是由于添加了固定数量的元数据,部分是由于效率较低的熵编码。

版本信息:

  • 作业系统(Linux)(uname -a):

    Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
    
  • 作业系统(Windows):

    在此处输入图片说明

  • GIMP(Linux):2.8.14(来自package gimp,版本2.8.14-1+deb8u1

    在此处输入图片说明

  • 窗口照片查看器(根据图像元数据):

    Microsoft Windows Photo Viewer 10.0.10586.0
    

20

编辑:在我知道文件大小增加了大约9 KiB(256×256图像为9055字节,512×512图像为9612 KiB)之前,发布了此答案。

极有可能在您第一次旋转图像时,Windows Picture Viewer会执行以下一项(或两项)操作:

  1. 添加了不在原始JPEG图像中的EXIF标签(也许是Orientation标签);
  2. 修改/添加的信息到已经存在的标签(可能是处理软件或图像软件标签)。

由于附加的EXIF标签(和/或现有标签的附加数据),这增加了文件大小。

随后的轮换并没有增加文件的大小,因为WPV本应添加/修改的所有标签和/或标签数据都已经存在。仅更改了方向标签(也许还有日期/时间标签值)。


编辑:几乎可以肯定,这种解释不能解决文件中大约9 KiB的其他数据。此外,在没有任何其他原因导致大小增加的情况下,这种解释将期望大小增加或多或少是恒定的(对数值数据的字符串表示之间的一些长度差取模,可能为几个字节)。显然这不是这里发生的事情,至少不是完整的解释。


1
而EXIF标签将占用9kB?好吧,至少这很容易测试-让OP从旋转的图像中删除EXIF或其他标签,并查看文件大小如何变化。
卡尔·威索夫特

2
@CarlWitthoft 9kB是新信息。编辑提到这一点。
scottbb '16

3

如果不对jpeg编码器/解码器进行逆向工程,就不可能确定。实际上存在许多jpeg标准,并且与流行的看法相反,并非所有这些标准都可以在不重新编码的情况下进行修改。

可能是第一个保存有损地重写为其喜欢的jpeg风格,随后的旋转是简单的元数据调整或直接在DCT表上进行的操作(某些编码方案可能如此)。

文件大小的增加可能还包括一些其他元数据,尽管9k看起来很多,但有可能。该增加也可以通过添加缩略图来解决,该缩略图可能不存在于GIMP的输出中。我们也许可以直接从文件中获取更多信息(在WPV之前和之后)。

在任何情况下,尝试与jpeg完美配合都是一种愚蠢的事情,因为它仅对某些图像尺寸有用,并非所有解码器和编码器都是相同的,并且要求那些编辑器直接处理您不能依赖的jpeg内容情况……仅仅因为现在这样做并不意味着将来会继续下去。

最好的选择是使用无损格式,并完全避免痛苦。


2
我根本不相信旋转jpeg数据首先应该引起重新编码。
卡尔·威索夫特

取决于您是否是程序员...我想您不是。您必须专门寻找该优化以进行最小的更改,否则保存操作将从未压缩的位图开始。
詹姆斯·斯内尔

3
从链接的问题来看,很明显Windows Photo Viewer确实无损旋转JPEG。
vclaw

2
@James我不是低级程序员,所以我在电视上播放:-)。OP提供了指向准确描述的链接,该描述准确说明何时需要重新编码,何时不重新编码。从那次讨论中,我推断出他只是在旋转$ \ frac {\ pi} {2} $。我同意任意角度旋转都会导致重新编码,因此,除非将X-by-Y图像嵌入至少与斜边一样大的区域中,否则这将导致信息丢失。
卡尔·威索夫特

1
我们可以肯定,我们知道 WPV为与8/16尺寸的倍数图像可逆转动。参见@Tristan对Matt Grum对OP中链接的问题的回答的评论。特里斯坦(Tristan)在Microsoft的WPV团队工作,并且基本上证实了这一点。
scottbb '16

1

如果图像尺寸是块尺寸的倍数(通常[/总是?] 8),则无损JPEG旋转只有在不引入边界伪影的情况下才可能进行。有关所涉及内容的详细信息,请参见jpegtran手册页(很抱歉,我没有很好的规范链接;如果找到一个,请随时进行编辑):

转置变换对图像
尺寸没有限制。如果图像尺寸不是iMCU尺寸的倍数(通常为8或16个像素),则其他转换操作会很奇怪,因为它们只能以所需的方式转换完整的DCT系数数据块。

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

在实际使用中,您可能更喜欢丢弃任何不可变形的
边缘像素,而不是在
转换后的图像的右侧和/或底部边缘上看起来很奇怪。为此,请添加-trim开关:

我怀疑Windows Photo Viewer通过在图像尺寸不是8的倍数时执行解压缩和超高质量重新压缩来模拟无损行为来避免此问题,而不是实际执行无损旋转。一个好的实用程序只会执行实际的无损,伪像和全部操作,或者丢失几个像素,而不会破坏整个图像的质量(并增加文件大小)。


1
与256x256图像无关。
部份

我误读并认为问题出在257x257版本。
R.,

0

我没有确切的答案,但是有一些可能的原因可以解释这一点。某些文件类型的工作方式是,该文件类型的图像的两个不同代码不一定会产生不同的图像。例如,PNG文件类型以这种方式工作,因为它允许透明的背景,但是具有透明背景且除了相同背景为白色的图像之外,其他图像都完全相同。如果一个图像文件每个像素占用少于3个字节的内存,则该图像文件被称为已压缩。我相信,除了具有透明背景的文件外,没有两个PNG文件会生成完全相同的图像。每当您将图片另存为PNG时,它都会将其转换为生成原始图片的代码,除了非常不寻常的图片(例如每个像素都是2 ^ 24种颜色的随机颜色)之外,该代码占用的内存少于每个像素3个字节,因此保存是因为PNG被称为无损压缩。另一方面,为了节省内存,JPEG图像文件的代码只能生成某些图像。可能有不止一种JPEG文件类型,我不知道它们中的任何一个是否具有属性,即该文件类型的两个不同图像可以生成完全相同的图像。我假设您旋转图像很多次,然后将其另存为JPEG,并会在假设您所做的假设不正确的情况下对发生的情况进行解释。如果有一种方法可以恢复与旋转并保存之前相同的图像文件代码,则所做的旋转是无损的。您确实做过无损轮换可能并不正确。如果真的是无损的


-3

其背后的原因有几个

图像的编码和压缩方式将仅由于压缩算法而改变大小。您可以通过将其另存为位图然后旋转来进行测试。在该格式或任何原始格式中,大小应保持不变。如果没有,则保存图像的程序将添加新数据,可能是一些元数据或其他内容。

但是,为什么要旋转jpeg 20次?


2
如果您阅读了原始问题中的链接,至少对于Windows Picture Viewer而言,如果JPEG的尺寸是8的倍数,则WPV 中JPEGS的旋转是无损转换。一种简单的测试方法是旋转4次(结果与原始方向相同)并执行简单的逐像素图像减法。
scottbb '16

@scottbb这不一定是Windows图片查看器的问题。旋转有损格式的任何内容都必须重新计算压缩率。以8的倍数旋转图像意味着所有内容都适合8位字,并且可能不会以增加伪影的方式进行压缩。这基于算法的工作原理并在所使用的程序中实现。
Cc Dd

-3

由于图像压缩的工作原理。通常,任何格式(例如PNG或JPG)在旋转后都不会保留文件大小。

对于压缩器来说,旋转后的图像只是一个不同的图像,由于压缩启发式的工作原理,无法保证将旋转后的图像压缩成相同的图像

当然,如果压缩是无损的,那么如果将图像第四次旋转4次,图像又会再次相同(旋转直到像原始图像一样倾斜):在这种情况下,图像应再次具有相同的压缩大小,否则这是因为以下原因之一

  • 添加了元数据:由于某种原因,程序添加了一些文本
  • 更改了Compressor:如果没有更改,程序可能会选择仅将图像重新保存为原始图像,但是如果您进行了任何更改(即使90度旋转4次),它可能会决定使用自己的图像再次重新压缩图像压缩程序(程序不再知道它仍然是同一图像)。
  • 通常,相同的压缩器(libPNG或libJPG)在不同的实现方式,相同库的不同版本以及不同的压缩参数下会产生非常不同的结果(有时操作系统和编译器也会有所不同)。

图像压缩通过将图像压缩为4x4或其他大小的块来工作。通常,压缩器将旋转的图像视为不同的图像,但是由于压缩的像素块只是线性分解,因此如果图像上的块相同,则可以有效地保持线性转置/镜像线性分解矩阵质量:

请注意,这必须在每个功能的基础上实现,并且还解释了大小的初始增加=>首次旋转时,它只是尝试将图像压缩为可旋转的块:

  • 如果这样做失败:图像质量下降
  • 如果成功,则仅增加一次大小,则每次旋转保持相同的质量。

  • 仅当图像由相等的块组成时,该操作才会成功。(图像大小是块大小的倍数)。

scottbb回答ins错误,您可以做一个简单的测试:

  • 打开原始图像:截图
  • 使用WPV将图像旋转4次:截图
  • 比较2个屏幕截图

您将看到图像已更改(在第一次旋转时已重新压缩)。但是,更改的时间是有限的,您现在可以再次旋转它而不会降低质量(如果图像的大小是8的倍数)

要直接回答OP:

我知道它旋转无损

并不是说旋转不是无损的,它至少会损失质量一次(第一次旋转时:因为它应该首先以一种可以旋转的方式压缩它),然后才能保持其质量。


1
问题在于无损旋转,因此避免了重新压缩。
Agent_L

5
OP询问的不是一般情况,而是有关该特定软件和执行该特定情况的确切问题。您的答案是正确的,它只是回答与OP要求不同的问题。
Agent_L

1
前三个句子仍然有一个不同的问题:“图像压缩如何工作”-无损旋转中没有压缩。“向压缩器旋转的图像”-再次,不调用压缩器。“如果压缩是无损的”-压缩是有损的。旋转是无损的。现在,这就是我愿意接受的论点。我同意你的观点,但我的观点完全不对。顺便说一句,我也是一名程序员,我也进行了原始文件读写工作。
Agent_L

1
我在Paint中创建了一个图像,将其旋转了4次,并且图像相同,但是大小从1.6 KB跃升到8.1 KB。二进制差异显示图像数据没有被触及,只是<?xpacket标签中大量的元数据。
Agent_L

1
如果JPEG的尺寸可以被8整除(或使用二次采样为16),则可以无损地将其旋转90度。关键是不要一直将其解码为RGB,而是直接使用DCT系数工作。这是一个专用功能,通常不包含在通用图像编辑器中。参见例如en.wikipedia.org/wiki/Libjpeg#jpegtran。如果按照问题中的说明使用Windows Photo Viewer进行了实验,您会发现它确实是无损的。
Mark Ransom
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.