Bash: самый быстрый способ определения размеров изображения из URL-адреса
Я пытаюсь найти действительно быстрый метод в bash для определения размеров изображений.
Я знаю, что смогу завести изображение, а затем использовать imagemagick для определения высоты и ширины изображения. Я обеспокоен тем, что это не самый быстрый способ сделать это.
- удалите бит на бит бит wget
- Вопрос о wget -qO-
- curl download отлично работает, но wget не работает с помощью ssl
- Как загрузить адрес электронной почты, который вызывается на веб-странице с помощью wget?
- Есть ли способ командной строки, с помощью которого я могу проверить, завершен ли или нет загруженный файл?
Я также заинтересован в том, чтобы установить imagemagick, когда мне нужен только небольшой набор функций. Я нахожусь в встроенной системе с очень ограниченными ресурсами (CPU, RAM, storage).
Есть идеи?
- Загрузить pdf-файлы с помощью wget
- Статическая компиляция wget
- Как сообщить wget для загрузки файлов с именами, закодированными url?
- Как запретить wget загружать списки каталога Apache в разных заказах?
- Загрузите список файлов, если они еще не существуют.
- Как Wget с условием подмножества + генерировать CHM / ... электронную книгу?
- wget изменение имени изображения изнутри страницы
- Как скопировать чужие папки с public.me.com с помощью wget-подобного инструмента?
5 Solutions collect form web for “Bash: самый быстрый способ определения размеров изображения из URL-адреса”
Как вы заметили, вам не нужен весь пакет ImageMagick . Вам просто нужно identify
.
Библиотекам также понадобятся исполняемые ссылки (и библиотеки, к которым эти библиотеки ссылаются).
> whereis identify identify: /bin/identify /usr/bin/identify /usr/share/man/man1/identify.1.gz > ldd /bin/identify
ldd
покажет список. Когда я это сделал, он включил некоторые библиотеки X libs, libjpeg и т. Д. И две библиотеки из пакета ImageMagick, libMagickCore
и libMagickWand
. Они смотрят, что связаны с одной и той же связью вещей, поэтому, если у вас есть это, identify
должна работать.
Вам не нужно загружать все изображение, чтобы получить размеры, потому что они находятся в заголовке в начале файла, и это то, на что identify
взгляд. Например, здесь я копирую первые 4 kB из полного jpeg в новый файл:
dd if=real.jpg of=test.jpg bs=1024 count=4
4 КБ должно быть более чем достаточно, чтобы включить заголовок – я уверен, что вы могли бы сделать это с 1/4 этой суммы. Теперь:
>identify test.jpg test.jpg JPEG 893x558 893x558+0+0 8-bit DirectClass 4.1KB 0.000u 0:00.000
Это правильные размеры для real.jpg
. Обратите внимание, однако, что размер (4.1KB) – это размер усеченного файла, поскольку эта информация не относится к заголовку изображения.
Итак: вам нужно загрузить только первый килобайт каждого изображения.
Вы можете использовать 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
новый блок, указанный двумя байтовыми маркерами, начинающимися с 0xff
. 0xffc0
содержащая информацию об измерениях, имеет значение 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. После магии и версии мы находим размеры. Пример из изображения 364×472:
<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, а затем читать следующие четыре для размеров.
Другие форматы:
Может быть, продолжал, но догадайся, что я сейчас останавливаюсь.
Предполагается, что вы «идентифицируете». Поместите это в скрипт и chmod +x <scriptname>
. Чтобы запустить его, введите <scriptname> picture.jpg
и вы получите высоту и ширину изображения. Первые 2 секции должны проверить, есть ли изображение, затем установите его как переменную IMAGE. Следующий раздел – убедиться, что файл на самом деле там. Последние 2 раздела должны вывести соответствующую информацию из вывода «ident» и отобразить ее.
#!/bin/bash if [[ "${#}" -ne "1" ]] then die "Usage: $0 <image>" fi IMAGE="${1}" if [[ ! -f "${IMAGE}" ]] then die "File not found: ${IMAGE}" fi IMG_CHARS=`identify "$1" | cut -f 3 -d' '` WIDTH=`echo $IMG_CHARS | cut -d'x' -f 1` HEIGHT=`echo $IMG_CHARS | cut -d'x' -f 2` echo -e "W: ${WIDTH} H: ${HEIGHT}"
mohsen@debian:~/codes/amlak/amlak/src$ file ~/Screenshot\ from\ 2013-07-10\ 01\:25\:34.png /home/mohsen/Screenshot from 2013-07-10 01:25:34.png: PNG image data, 1366 x 768, 8-bit/color RGB, non-interlaced
file command
по умолчанию устанавливается на distors и просто зависит от:
Depends: libc6 (>= 2.4), libmagic1 (= 1:5.14-2), zlib1g (>= 1:1.1.4)
Я думаю, вы можете легко установить его для встроенных. Вы просто пишете regular expression
для его вывода.
mohsen@debian:~/codes/amlak/amlak/src$ php -r "print_r(getimagesize('file:///archives/Picture/12 farvardin/20120331_013.jpg'));" Array ( [0] => 2560 [1] => 1440 [2] => 2 [3] => width="2560" height="1440" [bits] => 8 [channels] => 3 [mime] => image/jpeg ) mohsen@debian:~/codes/amlak/amlak/src$ php -r "print_r(getimagesize('file:///archives/Picture/12 farvardin/20120331_013.jpg'));" |egrep w [3] => width="2560" height="1440" mohsen@debian:~/codes/amlak/amlak/src$ php -r "print_r(getimagesize('file:///archives/Picture/12 farvardin/20120331_013.jpg'));" |egrep w | awk {'print $3'} width="2560" mohsen@debian:~/codes/amlak/amlak/src$ php -r "print_r(getimagesize('file:///archives/Picture/12 farvardin/20120331_013.jpg'));" |egrep w | awk {'print $4'} height="1440"
Вы заменяете file://
с помощью http://