回答:
お気づきのように、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パッケージから明らかに2つのライブラリーlibMagickCore
を含んでいましたlibMagickWand
。それらは同じものにリンクされているように見えるので、それがあれば動作するidentify
はずです。
寸法を取得するために画像全体をダウンロードする必要はありません。これは、これらがファイルの先頭のヘッダーにあり、それidentify
が見ているためです。たとえば、ここでは完全なjpegから最初の4 kBを新しいファイルにコピーしています。
dd if=real.jpg of=test.jpg bs=1024 count=4
ヘッダーを含めるには4 kBで十分です。その量の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)は切り捨てられたファイルのサイズです。
つまり、各画像の最初の1キロバイト程度をダウンロードするだけで済みます。
を使用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
ビッグエンディアン/モトローラマシンでは、次の方法でサイズを直接印刷することもできます。
hexdump -s16 -n8 -e '1/4 "%u" "\n"' sample.png
ただし、リトルエンディアン/インテルでは、それほど簡単ではなく、移植性も高くありません。
これにより、次のように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 ...
新しいブロックは、で始まる2バイトのマーカーで指定されて一緒に来ます0xff
。次元に関する情報を保持するものには値0xffc0
がありますが、データのかなり下に埋めることができます。
つまり、ブロックサイズのバイトをスキップし、マーカーをチェックし、ブロックサイズのバイトをスキップし、マーカーを読み取って、正しいバイトが来るまで続けます。
見つかった場合、サイズは、マーカーの後のオフセット3と5にそれぞれ2バイトずつ格納されます。
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.
いくつかのファイルと約10.000のjpg画像をチェックする単純なCプログラムを書いたところ、およそ50%が最初の500バイト以内のサイズ情報を持っていました。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
つまり、最初の6バイトをチェックしてgifかどうかを確認し、次の4バイトを読み取ってサイズを確認できます。
その他のフォーマット:
続けることができたかもしれませんが、私は今ここで停止すると思います。
あなたが「識別」していると仮定します。これをスクリプトに入れてくださいchmod +x <scriptname>
。それを実行するには、タイプする<scriptname> picture.jpg
と画像の高さと幅が得られます。最初の2つのセクションでは、画像があるかどうかを確認してから、IMAGE変数として設定します。次のセクションでは、ファイルが実際に存在することを確認します。最後の2つのセクションは、「識別」出力から関連情報を取得して表示することです。
#!/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
はデフォルトでディストーターにインストールされ、次のものに依存します
Depends: libc6 (>= 2.4), libmagic1 (= 1:5.14-2), zlib1g (>= 1:1.1.4)
組み込み用に簡単にインストールできると思います。regular expression
出力用にを書くだけです。
file
たとえば、.jpg
ファイルの寸法は提供しません。
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://