¿Hay alguna otra forma además de usar ImageIO.read para obtener la altura y el ancho de la imagen?
Porque encuentro un problema que bloquea el hilo.
at com.sun.medialib.codec.jpeg.Decoder.njpeg_decode(Native Method)
at com.sun.medialib.codec.jpeg.Decoder.decode(Decoder.java:87)
at com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader.decode(CLibJPEGImageReader.java:73)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at com.sun.media.imageioimpl.plugins.clib.CLibImageReader.getImage(CLibImageReader.java:320)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at com.sun.media.imageioimpl.plugins.clib.CLibImageReader.read(CLibImageReader.java:384)
- locked <0xd96fb668> (a com.sun.media.imageioimpl.plugins.jpeg.CLibJPEGImageReader)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at javax.imageio.ImageIO.read(ImageIO.java:1322)
Este error solo ocurre en un servidor de aplicaciones de Sun y, por lo tanto, sospecho que es un error de Sun.
java
javax.imageio
plata est
fuente
fuente
jstack
).Respuestas:
Aquí hay algo muy simple y útil.
fuente
Esta es una reescritura de la gran publicación de @Kay, que arroja IOException y proporciona una salida anticipada:
Supongo que mi reputación no es lo suficientemente alta como para que mi entrada se considere digna de respuesta.
fuente
javax.imageio.ImageIO.getImageReadersByMIMEType(mimeType)
si quisiera estar seguro del tipo de archivo?.close()
en la transmisión antes de regresar? de lo contrario, deja la transmisión abiertaorg.apache.commons.io.FilenameUtils#getExtension
para detectar la extensión del nombre de archivo.Encontré otra forma de leer el tamaño de una imagen (más genérica). Puede utilizar la clase ImageIO en cooperación con ImageReaders. Aquí está el código de ejemplo:
Tenga en cuenta que getFileSuffix es un método que devuelve la extensión de la ruta sin "." por ejemplo: png, jpg, etc. La implementación de ejemplo es:
Esta solución es muy rápida ya que solo se lee el tamaño de la imagen del archivo y no la imagen completa. Lo probé y no hay comparación con el rendimiento de ImageIO.read. Espero que alguien lo encuentre útil.
fuente
getFileSuffix()
contiene ifs innecesarios y poner sus iniciales connull
no es una buena idea en este caso.ImageIO.read()
completamente fuera del agua, tanto en términos de tiempo de CPU como de uso de memoria.Intenté probar el rendimiento utilizando algunos de los diversos enfoques enumerados. Es difícil hacer una prueba rigurosa ya que muchos factores afectan el resultado. Preparé dos carpetas, una con 330 archivos jpg y otra con 330 archivos png. El tamaño medio del archivo fue de 4 Mb en ambos casos. Luego llamé a getDimension para cada archivo. Cada implementación del método getDimension y cada tipo de imagen se probaron por separado (ejecución separada). Aquí están los tiempos de ejecución que obtuve (primer número para jpg, segundo número para png):
Es obvio que algunos métodos cargan todo el archivo para obtener dimensiones, mientras que otros lo hacen simplemente leyendo algo de información del encabezado de la imagen. Creo que estos números pueden ser útiles cuando el rendimiento de la aplicación es crítico.
Gracias a todos por la contribución a este hilo, muy útil.
fuente
Puede cargar datos binarios jpeg como un archivo y analizar los encabezados jpeg usted mismo. El que está buscando es el encabezado 0xFFC0 o Start of Frame:
Para obtener más información sobre los encabezados, consulte la entrada jpeg de wikipedia o obtuve la información anterior aquí .
Usé un método similar al código a continuación que obtuve de esta publicación en los foros de Sun:
}
fuente
==192
eso debería marcar los números 192-207, excepto 196, 200 y 204.com.drewnoakes.metadata-extractor
biblioteca para extraer fácilmente estos encabezadosManera simple:
fuente
El problema con ImageIO.read es que es muy lento. Todo lo que necesita hacer es leer el encabezado de la imagen para obtener el tamaño.
ImageIO.getImageReader
es candidato perfecto.Aquí está el ejemplo de Groovy, pero lo mismo se aplica a Java
El rendimiento fue el mismo que con la biblioteca java SimpleImageInfo.
https://github.com/cbeust/personal/blob/master/src/main/java/com/beust/SimpleImageInfo.java
fuente
getReaderByFormat
?Puede usar el kit de herramientas, sin necesidad de ImageIO
Si no desea manejar la carga de la imagen, hágalo
fuente
Puede obtener el ancho y el alto de la imagen con el objeto BufferedImage usando java.
fuente
Obtener una imagen almacenada en búfer con ImageIO.read es un método muy pesado, ya que crea una copia completa sin comprimir de la imagen en la memoria. Para png, también puede usar pngj y el código:
fuente
Habiendo luchado con
ImageIO
muchas cosas en los últimos años, creo que la solución de Andrew Taylor es, con mucho, el mejor compromiso (rápido: sin uso y versátil). ¡¡Gracias hombre!!ImageIO#read
Pero me sentí un poco frustrado al verme obligado a usar un archivo local (Archivo / Cadena), especialmente en los casos en los que desea verificar los tamaños de imagen que provienen, por ejemplo, de una solicitud de datos de formularios / múltiples partes donde generalmente recupera
InputPart
/InputStream
. Así que rápidamente hizo una variante que aceptaFile
,InputStream
yRandomAccessFile
, en base a la capacidad deImageIO#createImageInputStream
hacerlo.Por supuesto, tal método con
Object input
, solo puede permanecer privado y deberá crear tantos métodos polimórficos como sea necesario, llamando a este. También puede aceptarPath
conPath#toFile()
yURL
conURL#openStream()
antes de pasar a este método:fuente
Entonces, desafortunadamente, después de probar todas las respuestas anteriores, no logré que funcionen después de incansables intentos. Así que decidí hacer el truco real yo mismo y lo hice funcionar para mí. Confío en que también funcionará perfectamente para ti.
Estoy usando este método simple para obtener el ancho de una imagen generada por la aplicación y aún no cargarla más tarde para su verificación:
Por favor. tome nota: tendría que habilitar los permisos en el manifiesto para el almacenamiento de acceso.
/ Lo hice estático y lo puse en mi clase global para poder hacer referencia o acceder a él desde una sola fuente y, si hay alguna modificación, todo tendría que hacerse en un solo lugar. Simplemente manteniendo un concepto DRY en java. (de todos modos) :) /
}
fuente
Para obtener el tamaño del archivo emf sin el lector de imágenes EMF, puede usar el código:
fuente