Você pode usar curl
para baixar partes da imagem. Tudo depende de quão robusto tem que ser. Um caso de teste pode ser o primeiro de 500 bytes. Parece funcionar muito para png
e jpg
, depois use identify
ou algo parecido para verificar o tamanho.
curl -o 500-peek -r0-500 "http://example.net/some-image.png"
Editar:
Muito tempo desde que escrevi analisadores de imagem, mas pensei um pouco e atualizei parte da minha memória.
Eu suspeito que seja todo tipo de imagens que você deseja verificar (mas, novamente, talvez não). Vou descrever alguns dos mais comuns: PNG
, JPEG
(JFIF) e GIF
.
PNG:
Estes são simples quando se trata de extração de tamanho. Um cabeçalho png
armazena o tamanho dentro dos primeiros 24 bytes. Primeiro vem um cabeçalho fixo:
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.
Em seguida, vêm pedaços através do arquivo. Eles consistem em um campo fixo de comprimento, tipo e soma de verificação. Além disso, uma seção opcional data do tamanho tamanho .
Felizmente, o primeiro pedaço é sempre um IHDR
com esse layout:
byte description
0-3 Image Width
4-7 Image Height
8 Bits per sample or per palette index
... ...
Por isso, temos tamanhos que são bytes 16-20 e 21-24. Você pode despejar os dados, por exemplo, 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
Em uma máquina Big Endian / Motorola, também é possível imprimir os tamanhos diretamente por:
hexdump -s16 -n8 -e '1/4 "%u" "\n"' sample.png
No entanto, em Little Endian / Intel, não é assim tão fácil, e nem é muito portátil.
Por isso, podemos implementar um script bash + hexdump como em:
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
Mas isso não é diretamente eficiente. Embora exija um pedaço maior (75-100 bytes), identify
é bem mais rápido. Ou escreva a rotina em p. C, o que seria mais rápido do que as chamadas da biblioteca.
JPEG:
Quando se trata de jpg
, não é tão fácil. Ele também começa com um cabeçalho de assinatura , mas o bloco tamanho não está em um deslocamento fixo. Depois do cabeçalho:
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-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.
...
11-12 <version>
13 ...
um novo bloco vem especificado por um marcador de dois bytes começando com 0xff
. O que contém informações sobre dimensões tem o valor 0xffc0
, mas pode ser enterrado um pouco abaixo dos dados.
Em outras palavras, um ignora tamanho de bloco bytes, verifica marcador, pula tamanho de bloco bytes, lê marcador e assim por diante até que o correto apareça.
Quando encontrados, os tamanhos são armazenados por dois bytes cada no deslocamento 3 e 5 após marcador .
<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
Escreveu um programa C simples para verificar alguns arquivos e cerca de 10.000 imagens jpg, aproximadamente 50% tinham a informação de tamanho dentro dos primeiros 500 bytes, principalmente 50% entre ca. 100 e 200. O pior foi em torno de 80.000 bytes. Uma foto, enquanto falamos fotos:
GIF:
Emboragifgeralmentepossaterváriasimagensarmazenadasdentro,eletemumtamanhocanvasespecificadonocabeçalho,issoégrandeosuficienteparaabrigarasimagens.ÉtãofácilquantocomPNG,erequeratémesmofebre:10.Depoisdamágicaedaversão,encontramostamanhos.Exemplodeumaimagem364x472:
curl-o500-peek-r0-500"http://example.net/some-image.png"
Em outras palavras, você pode verificar os primeiros seis bytes para ver se é um gif e, em seguida, ler os próximos quatro para tamanhos.
Outros formatos:
Poderia ter continuado, mas acho que eu paro aqui por enquanto.