渐进式JPEG层/扫描偏移(imagemagick?)

渐进式JPEG层/扫描偏移(imagemagick?),imagemagick,jpeg,progressive,Imagemagick,Jpeg,Progressive,我一直在到处寻找,但都没有用。我希望能够提取每次渐进式JPEG层/扫描发生时的字节偏移量 例如,假设一个100KB的图像有5层用于渲染最终图像;第1层在kB 5处结束,第2层在kB 20处结束,第3层在kB 60处结束,等等(例如) 是否可以使用Imagemagick进行此操作?identify工具似乎不支持这样做。如果是,怎么做?否则,什么工具可以实现这一点?我宁愿不必编写自定义JPEG解析器。谢谢。您只需扫描图像流并查找SOS(开始扫描)标记。Christoph Erdmann在本文中提供了

我一直在到处寻找,但都没有用。我希望能够提取每次渐进式JPEG层/扫描发生时的字节偏移量

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


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

您只需扫描图像流并查找SOS(开始扫描)标记。

Christoph Erdmann在本文中提供了一些php示例代码:

$img=“progressive.jpg”;
$jpgdata=文件获取内容($img);
美元头寸=[];
$offset=0;
而($pos=strpos($jpgdata,“\xFF\xC4”,$offset)){
$positions[]=$pos+2;
$offset=$pos+2;
}

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

magick -interlace plane -size 400x200 gradient: progressive.jpg
exiftool
将告诉您很多关于它的信息,如下所示:

  exiftool -v3 progressive.jpg
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
样本输出

  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标记:

  exiftool -v3 progressive.jpg
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

,我想我可能需要做类似的事情。扫描二进制文件以查找字节标记的最佳方法是什么?我以前从未这样做过。你需要一份JPEG标准的副本。所有JPEG标记都以FF开头。某些标记具有长度字段,您必须使用这些字段跳过可能包含FF值的数据。剩下的部分,你扫描FF,只需跳过你不感兴趣的标记(包括FF00,意思是压缩的FF值),这真的很有用。谢谢你,先生!