Bash: самый быстрый способ определения размеров изображения из URL-адреса

Я пытаюсь найти действительно быстрый метод в bash для определения размеров изображений.

Я знаю, что смогу завести изображение, а затем использовать imagemagick для определения высоты и ширины изображения. Я обеспокоен тем, что это не самый быстрый способ сделать это.

Я также заинтересован в том, чтобы установить imagemagick, когда мне нужен только небольшой набор функций. Я нахожусь в встроенной системе с очень ограниченными ресурсами (CPU, RAM, storage).

Есть идеи?

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 байт. Картина, как мы говорим на фотографиях:

JFIF_SOF_graph


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://

  • Wget или скручивание самозаверяющего сертификата с сервера
  • Рекурсивная загрузка всех файлов из дочернего каталога веб-сайта с помощью wget
  • Получение файла с wget, когда имя файла может немного измениться
  • wget -k не конвертирует все ссылки
  • Почему команда curl использует URL-адреса с параметрами ввода
  • Предсказывать имя файла перед загрузкой с URL-адреса, в сценарии оболочки
  • не может wget rpm oracle на centos linux
  • Wget загружать файл (не перезаписывать) сценарий автоматического обновления
  • Почему возможно> / dev / null 2> & 1 не работает?
  • wget сохраняет файлы как обычные текстовые файлы при загрузке
  • wget, чтобы получить все файлы в каталоге, возвращает index.html
  • Interesting Posts

    В чем разница между `/ sbin / ip route` и` / sbin / route`?

    Rsync – Поврежденный MAC на входе

    команда терминала, которая печатает вкладки, пробелы и символы новой строки как \ t \ s и \ n

    Почему sudo env не показывает все переменные среды?

    Как правильно проверить расширение файла в инструкции if?

    Как случайным образом изменить фоновое изображение Gnome с помощью bash?

    Когда ядро ​​сокращает дейтаграмму UDP в куски MTU?

    перенести все логические тома (включая swap и /) на новый диск

    Каковы способы повышения стабильности системы и предотвращения потери данных в условиях частых жестких перезагрузок и / или паники ядра?

    Не удается добавить пользователя в группу?

    ld не может найти -lGL на CentOS 7

    Как увеличить количество массивов семафоров в Linux?

    Как удалить файл с именем -help с командной строки bash?

    OpenSSL конвертирует символы в UTF-8

    Не удается подключиться к VPN с помощью ipsec после обновления

    Linux и Unix - лучшая ОС в мире.