Puede usar curl
para descargar partes de la imagen. Todo depende de cuán robusto tenga que ser. Un caso de prueba podría ser los primeros 500 bytes. Parece funcionar por mucho tiempo png
y jpg
luego usar identify
o algo similar para verificar el tamaño.
curl -o 500-peek -r0-500 "http://example.net/some-image.png"
Editar:
Hace mucho tiempo que escribí analizadores de imágenes, pero lo pensé y refresqué parte de mi memoria.
Sospecho que es todo tipo de imágenes que desea verificar (pero, de nuevo, tal vez no). Voy a describir algunos de los más comunes: PNG
, JPEG
(JFIF) y GIF
.
PNG:
Estos son simples cuando se trata de extracción de tamaño. Un png
encabezado almacena el tamaño dentro de los primeros 24 bytes. Primero viene un encabezado fijo:
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.
Luego viene fragmentos a través del archivo. Consisten en un campo fijo de longitud, tipo y suma de verificación. Además, una sección de datos opcional de tamaño de longitud .
Afortunadamente, el primer fragmento siempre es un IHDR
con este diseño:
byte description
0-3 Image Width
4-7 Image Height
8 Bits per sample or per palette index
... ...
Por esto tenemos que los tamaños son byte 16-20 y 21-24. Puede volcar los datos, por ejemplo, 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
En una máquina Big Endian / Motorola, también se pueden imprimir los tamaños directamente:
hexdump -s16 -n8 -e '1/4 "%u" "\n"' sample.png
Sin embargo, en Little Endian / Intel, no es tan fácil y tampoco es muy portátil.
Con esto, podríamos implementar un script bash + hexdump como en:
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
Pero, esto no es directamente eficiente. Aunque requiere una porción mayor (75-100 bytes), identify
es bastante más rápido. O escriba la rutina en, por ejemplo, C, que sería más rápido que las llamadas a la biblioteca.
JPEG:
Cuando se trata de jpg
eso, no es tan fácil. También comienza con un encabezado de firma , pero el tamaño del fragmento no está en un desplazamiento fijo. Después del encabezado:
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 ...
aparece un nuevo bloque especificado por un marcador de dos bytes que comienza con 0xff
. El que contiene información sobre las dimensiones tiene el valor, 0xffc0
pero puede ocultarse un poco por debajo de los datos.
En otras palabras, omitir bytes de tamaño de bloque , marcar marcador, omitir bytes de tamaño de bloque , leer marcador, etc. hasta que aparezca el correcto.
Cuando se encuentran, los tamaños se almacenan en dos bytes cada uno en el desplazamiento 3 y 5 después del marcador .
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.
Escribió un programa en C simple para verificar algunos archivos y de aproximadamente 10,000 imágenes jpg, aproximadamente el 50% tenía la información de tamaño dentro de los primeros 500 bytes, principalmente el 50% entre ca. 100 y 200. Lo peor fue alrededor de 80,000 bytes. Una foto, mientras hablamos fotos:
GIF:
Aunque el GIF generalmente puede tener múltiples imágenes almacenadas, tiene un tamaño de lienzo especificado en el encabezado, esto es lo suficientemente grande como para albergar las imágenes. Es tan fácil como con PNG , y requiere incluso bytes de fiebre: 10. Después de la magia y la versión, encontramos tamaños. Ejemplo de una imagen de 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
En otras palabras, puede verificar los primeros seis bytes para ver si es un gif, luego leer los siguientes cuatro para ver los tamaños.
Otros formatos:
Podría haber continuado, pero supongo que me detengo aquí por ahora.