linux - tamaños - Forma rápida de obtener dimensiones de imagen(no tamaño de archivo)
reducir tamaño de imagen en linux (7)
No estoy seguro de que tenga instalado php, pero esta función PHP es bastante útil
php -r "print_r(getimagesize(''http://www.google.com/images/logos/ps_logo2.png''));"
Estoy buscando una manera rápida de obtener el alto y el ancho de una imagen en píxeles. Debe manejar al menos JPG, PNG y TIFF, pero cuanto más, mejor. Lo enfatizo rápido porque mis imágenes son bastante grandes (hasta 250 MB) y lleva mucho tiempo obtener el tamaño con la identify
de ImageMagick porque obviamente lee primero las imágenes como un todo.
Preferiblemente, busco una forma que funcione bien en Ruby, o incluso en Rails 3.
Conozco las cosas de la teoría (varios formatos de imagen, sus encabezados y sus diferencias, etc.). De hecho, solicito algún tipo de biblioteca que pueda resolver mi problema de una manera bastante genérica.
Acabo de encontrar http://imagesize.rubyforge.org que parece prometedor aunque el desarrollo parece estar muerto.
Puede usar la función de identify de ImageMagick. Así es como lo haces en bash (Nota $ 0 es la ruta de la imagen):
width=$(identify -format "%w" "$0")> /dev/null
height=$(identify -format "%h" "$0")> /dev/null
Y esto también oculta cualquier posible mensaje de error. Las implementaciones modernas de identify
solo leen el encabezado, no toda la imagen, por lo que es rápido. Sin embargo, no estoy seguro de cómo se compara con otros métodos.
Si tiene información EXIF en las imágenes, puede leer el encabezado EXIF.
Son las dimensiones en píxeles que deseas (ancho y alto), supongo.
Creo que la mayoría de los formatos de archivo tienen información de encabezado que define las dimensiones, de modo que el software que lee el archivo pueda saber cuánto espacio debe reservar antes de comenzar a leer el archivo. Algunos formatos de archivos "en bruto" pueden ser simplemente una secuencia de bytes con un byte "final de línea" al final de cada fila horizontal de píxeles (en cuyo caso el software debe leer la primera línea y dividir el tamaño de la secuencia de bytes) por la longitud de la línea para obtener la altura).
No creo que pueda hacer esto de una manera "genérica", ya que necesita comprender el formato de archivo (o usar una biblioteca por supuesto) para saber cómo leerlo. Probablemente pueda encontrar algún código que en la mayoría de los casos proporcione una estimación aproximada de las dimensiones sin leer todo el archivo, pero creo que algunos tipos de archivos pueden requerir que lea todo el archivo para asegurarse de qué dimensiones realmente tiene. Espero que la mayoría de los formatos de imagen centrados en web tengan un encabezado con dicha información para que el navegador pueda crear las dimensiones del cuadro antes de que se cargue la imagen completa.
Supongo que una buena biblioteca tendría algunos métodos para obtener las dimensiones de los archivos que maneja, y que esos métodos se implementarían de la manera más eficiente posible.
Actualización : imageinfo parece que hace lo que quieres. (No lo he probado)
https://joseluisbz.wordpress.com/2013/08/06/obtaining-size-or-dimension-of-images/ (BMP, PNG, GIF, JPG, TIF o WMF)
Aquí para dos formatos PNG y JPG.
Mi código es de una clase diseñada para mi uso, puede editar según sus necesidades.
Por favor, compruebe estas funciones / método usando PHP :
public function ByteStreamImageString($ByteStream,&$Formato,&$Alto,&$Ancho) {
$Alto = 0;
$Ancho = 0;
$Formato = -1;
$this->HexImageString = "Error";
if (ord($ByteStream[0])==137 && ord($ByteStream[1])==80 && ord($ByteStream[2])==78){
$Formato = 1; //PNG
$Alto = $this->Byte2PosInt($ByteStream[22],$ByteStream[23]);
$Ancho = $this->Byte2PosInt($ByteStream[18],$ByteStream[19]);
}
if (ord($ByteStream[0])==255 && ord($ByteStream[1])==216
&& ord($ByteStream[2])==255 && ord($ByteStream[3])==224){
$Formato = 2; //JPG
$PosJPG = 2;
while ($PosJPG<strlen($ByteStream)){
if (sprintf("%02X%02X", ord($ByteStream[$PosJPG+0]),ord($ByteStream[$PosJPG+1]))=="FFC0"){
$Alto = $this->Byte2PosInt($ByteStream[$PosJPG+5],$ByteStream[$PosJPG+6]);
$Ancho = $this->Byte2PosInt($ByteStream[$PosJPG+7],$ByteStream[$PosJPG+8]);
}
$PosJPG = $PosJPG+2+$this->Byte2PosInt($ByteStream[$PosJPG+2],$ByteStream[$PosJPG+3]);
}
}
if ($Formato > 0){
$this->HexImageString = "";
$Salto = 0;
for ($i=0;$i < strlen($ByteStream); $i++){
$Salto++;
$this->HexImageString .= sprintf("%02x", ord($ByteStream[$i]));
if ($Salto==64){
$this->HexImageString .= "/n";
$Salto = 0;
}
}
}
}
private function Byte2PosInt($Byte08,$Byte00) {
return ((ord($Byte08) & 0xFF) << 8)|((ord($Byte00) & 0xFF) << 0);
}
Usando el código PHP:
$iFormato = NULL;//Format PNG or JPG
$iAlto = NULL; //High
$iAncho = NULL;//Wide
ByteStreamImageString($ImageJPG,$iFormato,$iAlto,$iAncho);//The Dimensions will stored in iFormato,iAlto,iAncho
Ahora estas funciones / método usando JAVA :
private void ByteStreamImageString(byte[] ByteStream,int[] Frmt,int[] High,int[] Wide) {
High[0] = 0;
Wide[0] = 0;
Frmt[0] = -1;
this.HexImageString = "Error";
if ((int)(ByteStream[0]&0xFF)==137 && (int)(ByteStream[1]&0xFF)==80 &&(int)(ByteStream[2]&0xFF)==78){
Frmt[0] = 1; //PNG
High[0] = this.Byte2PosInt(ByteStream[22],ByteStream[23]);
Wide[0] = this.Byte2PosInt(ByteStream[18],ByteStream[19]);
}
if ((int)(ByteStream[0]&0xFF)==255 && (int)(ByteStream[1]&0xFF)==216
&&(int)(ByteStream[2]&0xFF)==255 && (int)(ByteStream[3]&0xFF)==224){
Frmt[0] = 2; //JPG
int PosJPG = 2;
while (PosJPG<ByteStream.length){
if (String.format("%02X%02X", ByteStream[PosJPG+0],ByteStream[PosJPG+1]).equals("FFC0")){
High[0] = this.Byte2PosInt(ByteStream[PosJPG+5],ByteStream[PosJPG+6]);
Wide[0] = this.Byte2PosInt(ByteStream[PosJPG+7],ByteStream[PosJPG+8]);
}
PosJPG = PosJPG+2+this.Byte2PosInt(ByteStream[PosJPG+2],ByteStream[PosJPG+3]);
}
}
if (Frmt[0] > 0){
this.HexImageString = "";
int Salto = 0;
for (int i=0;i < ByteStream.length; i++){
Salto++;
this.HexImageString += String.format("%02x", ByteStream[i]);
if (Salto==64){
this.HexImageString += "/n";
Salto = 0;
}
}
}
}
private Integer Byte2PosInt(byte Byte08, byte Byte00) {
return new Integer (((Byte08 & 0xFF) << 8)|((Byte00 & 0xFF) << 0));
}
Usando el código de Java:
int[] iFormato = new int[1]; //Format PNG or JPG
int[] iAlto = new int[1]; //High
int[] iAncho = new int[1]; //Wide
ByteStreamImageString(ImageJPG,iFormato,iAlto,iAncho); //The Dimensions will stored in iFormato[0],iAlto[0],iAncho[0]
-ping es una opción que parece haber introducido para ese propósito.
Sin embargo, a partir de ImageMagick 6.7.7 no observo desaceleración incluso para todos los archivos de gran tamaño, por ejemplo:
head -c 100000000 /dev/urandom > f.gray
# I don''t recommend that you run this command as it eats a lot of memory.
convert -depth 8 -size 20000x10000 f.gray f.png
identify f.png
¿Puedes producir una imagen de entrada de ejemplo para la que todavía es lenta?
El comando de
file
imprime las dimensiones para varios formatos de imagen (por ejemplo, PNG, GIF, JPEG, pero no PPM, WEBP), y solo lee el encabezado.exiv2
le da dimensiones para muchos formatos, incluyendo JPEG, TIFF, PNG, GIF, WEBP, incluso si no hay un encabezado EXIF presente. Sin embargo, no está claro si se lee toda la información para eso. Consulte la página de manual de exiv2 para conocer todos los formatos de imagen admitidos.El comando de
identify
(de ImageMagick) imprime mucha información de imagen para una amplia variedad de imágenes. Parece limitarse a leer la parte del encabezado (ver comentarios).head -n1
le dará las dimensiones de los formatos PPM, PGM.
Para formatos populares en la web, tanto exiv2
como identify
harán el trabajo. Dependiendo del caso de uso, puede que necesite escribir su propia secuencia de comandos que combine / analice los resultados de varias herramientas.