Вы можете использовать curl
для загрузки частей изображения. Все зависит от того, насколько надежным он должен быть. Тестовый случай может быть первым 500 байтов. Кажется, для работы много, png
а jpg
затем используйте identify
или как, чтобы проверить размер.
curl -o 500-peek -r0-500 "http://example.net/some-image.png"
Редактировать:
Я давно писал парсеры изображений, но немного подумал и освежил часть своей памяти.
Я подозреваю, что это все виды изображений, которые вы хотите проверить (но опять же, возможно, нет). Я опишу некоторые из наиболее распространенных из них: PNG
, JPEG
(JFIF) и GIF
.
PNG:
Это просто, когда дело доходит до извлечения размера. png
Заголовка хранит размер в пределах первых 24 байт. Сначала идет фиксированный заголовок:
byte value description
0 0x89 Bit-check. 0x89 has bit 7 set.
1-3 PNG The letters P,N and G
4-5 \r\n Newline check.
6 ^z MS-DOS won't print data beyond this using `print`
7 \n *nix newline.
Далее идут куски через файл. Они состоят из фиксированного поля длины, типа и контрольной суммы. Кроме того необязательных данные секция длиной размера.
К счастью, первый блок всегда IHDR
с таким макетом:
byte description
0-3 Image Width
4-7 Image Height
8 Bits per sample or per palette index
... ...
Таким образом, мы имеем размеры 16-20 и 21-24. Вы можете вывести данные, например, с помощью hexdump:
hexdump -vn29 -e '"Bit-test: " /1 "%02x" "\n" "Magic : " 3/1 "%_c" "\n" "DOS-EOL : " 2/1 "%02x" "\n" "DOS-EOF : " /1 "%02x" "\n" "NIX-EOL : " /1 "%02x" "\n" "Chunk Size: " 4/1 "%02u" "\n" "Chunk-type: " 4/1 "%_c" "\n" "Img-Width : " 4/1 "%02x" "\n" "Img-Height: " 4/1 "%02x" "\n" /1 "Depth : %u bit" "\n" /1 "Color : %u" "\n" /1 "Compr.: %u" "\n" /1 "Filter: %u" "\n" /1 "Interl: %u" "\n"' sample.png
На машине Big Endian / Motorola можно также распечатать размеры напрямую:
hexdump -s16 -n8 -e '1/4 "%u" "\n"' sample.png
Однако на Little Endian / Intel это не так просто и не очень портативно.
Таким образом, мы можем реализовать скрипт bash + hexdump, как в:
png_hex='16/1 "%02x" " " 4/1 "%02x" " " 4/1 "%02x" "\n"'
png_valid="89504e470d0a1a0a0000000d49484452"
function png_wh()
{
read -r chunk1 img_w img_h<<<$(hexdump -vn24 -e "$png_hex" "$1")
if [[ "$chunk1" != "$png_valid" ]]; then
printf "Not valid PNG: \`%s'\n" "$1" >&2
return 1
fi
printf "%10ux%-10u\t%s\n" "0x$img_w" "0x$img_h" "$1"
return 0
}
if [[ "$1" == "-v" ]]; then verbose=1; shift; fi
while [[ "$1" ]]; do png_wh "$1"; shift; done
Но это не совсем эффективно. Хотя для этого требуется больший кусок (75-100 байт), он identify
работает довольно быстро. Или напишите подпрограмму, например, в C, которая будет быстрее, чем вызовы библиотеки.
JPEG:
Когда дело доходит до jpg
этого не так просто. Он также начинается с заголовка подписи , но размер блока не с фиксированным смещением. После заголовка:
byte value
0-1 ffd8 SOI (Start Of Image)
2-3 ffe0 JFIF marker
4-5 <block-size> Size of this block including this number
6-10 JFIF\0 ...
11-12 <version>
13 ...
появляется новый блок, указанный двухбайтовым маркером, начинающимся с 0xff
. Тот, который содержит информацию об измерениях, имеет значение, 0xffc0
но может быть скрыт в данных.
Другими словами, один пропускает байты размера блока , проверяет маркер, пропускает байты размера блока , читает маркер и так далее, пока не появится правильный.
Найденные размеры сохраняются по два байта каждый со смещением 3 и 5 после маркера .
0-1 ffc0 SOF marker
2-3 <block-size> Size of this block including this number
4 <bits> Sample precision.
5-6 <Y-size> Height
7-8 <X-size> Width
9 <components> Three for color baseline, one for grayscale.
Написал простую C-программу для проверки некоторых файлов и около 10.000 изображений в формате jpg, примерно 50% имели информацию о размере в первых 500 байтах, в основном 50% между ок. 100 и 200. Худшее было около 80.000 байтов. Картинка, как мы говорим, картинки:
GIF:
Хотя GIF обычно может иметь несколько изображений , хранящихся внутри, он имеет брезентовый размер , указанный в заголовке, это достаточно большая для размещения изображений. Это так же просто, как с PNG , и требует даже байтов лихорадки: 10. После магии и версии мы находим размеры. Пример из изображения 364x472:
<byte> <hex> <value>
0-2 474946 GIF Magic
3-5 383961 89a Version (87a or 89a)
6-7 6c01 364 Logical Screen Width
8-9 d801 472 Logical Screen Height
Другими словами, вы можете проверить первые шесть байтов, чтобы увидеть, если это GIF, а затем прочитать следующие четыре для размеров.
Другие форматы:
Можно было бы продолжить, но, думаю, я остановлюсь здесь сейчас.