1

我一直在寻找高低无济于事。我希望能够提取每个渐进式 JPEG 图层/扫描发生的字节偏移量。

例如,假设一个 100 kB 的图像有 5 层用于渲染最终图像;第 1 层在 kB 5 处结束,第 2 层在 kB 20 处结束,第 3 层在 kB 60 处结束,等等(例如)。

是否可以为此使用 Imagemagick?该identify工具似乎不支持这样做。如果是这样,怎么做?否则有什么工具可以做到这一点?我宁愿不必编写自定义 JPEG 解析器。谢谢。

4

3 回答 3

1

您可以使用ImageMagick制作像这样的渐进式 JPEG进行测试:

magick -interlace plane -size 400x200 gradient: progressive.jpg

exiftool会告诉你很多这样的事情:

  exiftool -v3 progressive.jpg

样本输出

  ExifToolVersion = 12.00
  FileName = progressive.jpg
  Directory = .
  FileSize = 2709
  FileModifyDate = 1620144585
  FileAccessDate = 1620144586
  FileInodeChangeDate = 1620144585
  FilePermissions = 33188
  FileType = JPEG
  FileTypeExtension = JPG
  MIMEType = image/jpeg
JPEG APP0 (14 bytes):
    0006: 4a 46 49 46 00 01 01 00 00 01 00 01 00 00       [JFIF..........]
  + [BinaryData directory, 9 bytes]
  | JFIFVersion = 1 1
  | - Tag 0x0000 (2 bytes, int8u[2]):
  |     000b: 01 01                                           [..]
  | ResolutionUnit = 0
  | - Tag 0x0002 (1 bytes, int8u[1]):
  |     000d: 00                                              [.]
  | XResolution = 1
  | - Tag 0x0003 (2 bytes, int16u[1]):
  |     000e: 00 01                                           [..]
  | YResolution = 1
  | - Tag 0x0005 (2 bytes, int16u[1]):
  |     0010: 00 01                                           [..]
  | ThumbnailWidth = 0
  | - Tag 0x0007 (1 bytes, int8u[1]):
  |     0012: 00                                              [.]
  | ThumbnailHeight = 0
  | - Tag 0x0008 (1 bytes, int8u[1]):
  |     0013: 00                                              [.]
JPEG DQT (65 bytes):
    0018: 00 03 02 02 02 02 02 03 02 02 02 03 03 03 03 04 [................]
    0028: 06 04 04 04 04 04 08 06 06 05 06 09 08 0a 0a 09 [................]
    0038: 08 09 09 0a 0c 0f 0c 0a 0b 0e 0b 09 09 0d 11 0d [................]
    0048: 0e 0f 10 10 11 10 0a 0c 12 13 12 10 13 0f 10 10 [................]
    0058: 10                                              [.]
JPEG SOF2 (9 bytes):
    005d: 08 00 c8 01 90 01 01 11 00                      [.........]
  ImageWidth = 400
  ImageHeight = 200
  EncodingProcess = 2
  BitsPerSample = 8
  ColorComponents = 1
JPEG DHT (20 bytes):
    006a: 00 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    007a: 00 00 04 08                                     [....]
JPEG SOS
JPEG DHT (19 bytes):
    0139: 10 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    0149: 00 00 12                                        [...]
JPEG SOS
JPEG DHT (18 bytes):
    0468: 10 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    0478: 00 a0                                           [..]
JPEG SOS
JPEG DHT (20 bytes):
    048a: 10 01 01 01 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    049a: 00 71 00 70                                     [.q.p]
JPEG SOS
JPEG SOS
JPEG DHT (21 bytes):
    0728: 10 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00 [................]
    0738: 00 01 71 00 50                                  [..q.P]
JPEG SOS
JPEG EOI

您还可以像这样找到 SOS 标记:

xxd -c16 -g1 -u progressive.jpg | grep --color=always -A4 "FF DA"
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 04 08 FF DA  ................
00000080: 00 08 01 01 00 00 00 01 D4 60 00 00 00 00 00 08  .........`......
00000090: 40 00 00 00 00 00 11 00 00 00 00 00 00 21 00 00  @............!..
000000a0: 00 00 00 00 42 00 00 00 00 00 00 88 00 00 00 00  ....B...........
000000b0: 00 01 08 00 00 00 00 00 02 10 00 00 00 00 00 04  ................
--
00000140: 00 00 00 00 00 00 00 00 00 00 00 12 FF DA 00 08  ................
00000150: 01 01 00 01 05 02 B5 AD 6B 5A D6 B5 AD 6B 5A D6  ........kZ...kZ.
00000160: B5 AD 6B 5A D6 B5 AD 6B 5A D6 B5 AD 6B 5A D6 B5  ..kZ...kZ...kZ..
00000170: AD 6B 5A D6 B5 AD 6B 5A D6 B5 AD 6B 5A D6 B5 AD  .kZ...kZ...kZ...
00000180: 6B 5A D6 B5 AD 6B 5A D6 B5 AD 6B 5A D6 B5 AD 6B  kZ...kZ...kZ...k

如果它们落在 16 字节的行尾,它可能会错过一些标记 - 我仍在考虑使这个万无一失。也许以 4 字节的偏移量运行它两次,这样它们就不会落在两个列表的边界上。

或者,我在这里做了另一个答案,可让您查找可以轻松适应的任意二进制序列,从查找 TIFF 标头到查找FF DA.

于 2021-05-04T16:21:12.437 回答
0

您所要做的就是扫描图像流并查找 SOS(扫描开始)标记。

于 2016-03-17T02:51:54.023 回答
0

Christoph Erdmann 在这篇文章中有一些 php 示例代码:

https://www.smashingmagazine.com/2019/08/faster-image-loading-embedded-previews/#creating-frontend-javascript-code

$img = "progressive.jpg";
$jpgdata = file_get_contents($img);
$positions = [];
$offset = 0;
while ($pos = strpos($jpgdata, "\xFF\xC4", $offset)) {
    $positions[] = $pos+2;
    $offset = $pos+2;
}
于 2021-05-03T04:00:27.317 回答