我一直在寻找高低,但无济于事。我希望能够提取每个渐进式JPEG图层/扫描发生的字节偏移。
例如,假设一个100 kB图像有5层用于渲染最终图像;第1层以kB 5结束,第2层以kB 20结束,第3层以kB 60等结束(例如)。
是否可以使用Imagemagick? identify
工具似乎不支持这样做。如果是这样,怎么样?否则,哪些工具可以实现这一目标?我宁愿不必编写自定义JPEG解析器。感谢。
答案 0 :(得分: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 字节的偏移量运行它两次,这样它们就不会落在两个列表的边界上。
或者,我做了另一个答案 here,它可以让您查找任意二进制序列,您可以轻松地从查找 TIFF 标头到查找 FF DA
。
答案 1 :(得分:0)
您所要做的就是扫描图像流并查找SOS(扫描开始)标记。
答案 2 :(得分:0)
Christoph Erdmann 在这篇文章中有一些 php 示例代码:
$img = "progressive.jpg";
$jpgdata = file_get_contents($img);
$positions = [];
$offset = 0;
while ($pos = strpos($jpgdata, "\xFF\xC4", $offset)) {
$positions[] = $pos+2;
$offset = $pos+2;
}