Existe alguma outra maneira além de usar ImageIO.read para obter a altura e largura da imagem?
Porque encontro um problema que bloqueia o thread.
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)
Esse erro ocorre apenas em um servidor de aplicativo Sun e, portanto, suspeito que seja um bug da Sun.
java
javax.imageio
prata est
fonte
fonte
jstack
).Respostas:
Aqui está algo muito simples e prático.
fonte
Esta é uma reescrita da excelente postagem de @Kay, que lança IOException e fornece uma saída antecipada:
Acho que minha representação não é alta o suficiente para que minha opinião seja considerada válida como resposta.
fonte
javax.imageio.ImageIO.getImageReadersByMIMEType(mimeType)
se quisesse ter certeza do tipo de arquivo?.close()
para a transmissão antes de retornar? caso contrário, você deixa o stream abertoorg.apache.commons.io.FilenameUtils#getExtension
para detectar a extensão do nome do arquivo.Encontrei outra maneira de ler o tamanho da imagem (mais genérico). Você pode usar a classe ImageIO em cooperação com ImageReaders. Aqui está o código de exemplo:
Observe que getFileSuffix é um método que retorna a extensão do caminho sem "." por exemplo: png, jpg etc. O exemplo de implementação é:
Esta solução é muito rápida, pois apenas o tamanho da imagem é lido do arquivo e não da imagem inteira. Eu testei e não há comparação com o desempenho de ImageIO.read. Espero que alguém ache isso útil.
fonte
getFileSuffix()
contém ifs desnecessários e inicializar comnull
não é uma boa ideia neste caso.ImageIO.read()
completamente fora da água, tanto em termos de tempo de CPU e memória.Tentei testar o desempenho usando algumas das várias abordagens listadas. É difícil fazer um teste rigoroso, pois muitos fatores afetam o resultado. Preparei duas pastas, uma com 330 arquivos jpg e outra com 330 arquivos png. O tamanho médio do arquivo foi de 4 Mb em ambos os casos. Em seguida, chamei getDimension para cada arquivo. Cada implementação do método getDimension e cada tipo de imagem foi testado separadamente (execução separada). Aqui estão os tempos de execução que obtive (primeiro número para jpg, segundo número para png):
É óbvio que alguns métodos carregam o arquivo inteiro para obter as dimensões, enquanto outros obtêm apenas lendo algumas informações do cabeçalho da imagem. Acho que esses números podem ser úteis quando o desempenho do aplicativo é crítico.
Obrigado a todos pela contribuição para este tópico - muito útil.
fonte
Você pode carregar dados binários jpeg como um arquivo e analisar os cabeçalhos jpeg você mesmo. O que você está procurando é o cabeçalho 0xFFC0 ou Start of Frame:
Para obter mais informações sobre os cabeçalhos, verifique a entrada jpeg da wikipedia ou eu tenho as informações acima aqui .
Usei um método semelhante ao código a seguir, obtido nesta postagem nos fóruns da Sun:
}
fonte
==192
disso deveria verificar os números 192-207, exceto 196, 200 e 204.com.drewnoakes.metadata-extractor
biblioteca para extrair facilmente esses cabeçalhosManeira simples:
fonte
O problema com ImageIO.read é que ele é muito lento. Tudo que você precisa fazer é ler o cabeçalho da imagem para obter o tamanho.
ImageIO.getImageReader
é o candidato perfeito.Aqui está o exemplo do Groovy, mas a mesma coisa se aplica ao Java
O desempenho foi o mesmo que usar a biblioteca Java SimpleImageInfo.
https://github.com/cbeust/personal/blob/master/src/main/java/com/beust/SimpleImageInfo.java
fonte
getReaderByFormat
?Você pode usar o Toolkit, sem necessidade de ImageIO
Se você não quiser lidar com o carregamento da imagem, faça
fonte
Você pode obter a largura e a altura da imagem com o objeto BufferedImage usando java.
fonte
Obter uma imagem com buffer com ImageIO.read é um método muito pesado, pois cria uma cópia descompactada completa da imagem na memória. Para png's, você também pode usar pngj e o código:
fonte
Tendo lutado
ImageIO
muito nos últimos anos, acho que a solução de Andrew Taylor é de longe o melhor meio-termo (rápido: não usar e versátil). Obrigado cara !!ImageIO#read
Mas fiquei um pouco frustrado por ser obrigado a usar um arquivo local (Arquivo / String), especialmente nos casos em que você deseja verificar os tamanhos de imagem provenientes de, digamos, uma solicitação multipart / form-data onde você normalmente recupera
InputPart
/InputStream
's. Então eu rapidamente fez uma variante que aceitaFile
,InputStream
eRandomAccessFile
, com base na capacidade deImageIO#createImageInputStream
fazê-lo.Claro, tal método com
Object input
, pode permanecer privado e você deve criar tantos métodos polimórficos quantos forem necessários, chamando este. Você também pode aceitarPath
comPath#toFile()
eURL
comURL#openStream()
antes de passar para este método:fonte
Então, infelizmente, depois de tentar todas as respostas acima, eu não consegui que funcionassem depois de tentativas incansáveis. Então eu decidi fazer o hack de verdade sozinho e vou trabalhar para mim. Acredito que funcionaria perfeitamente para você também.
Estou usando este método simples para obter a largura de uma imagem gerada pelo aplicativo e ainda para ser enviada posteriormente para verificação:
Pls. tome nota: você teria que habilitar as permissões no manifesto para acessar o armazenamento.
/ Eu o tornei estático e coloquei minha classe Global para que eu possa referenciá-lo ou acessá-lo de apenas uma fonte e se houver alguma modificação, tudo teria que ser feito em apenas um lugar. Apenas mantendo um conceito DRY em java. (de qualquer maneira) :) /
}
fonte
Para obter o tamanho do arquivo emf sem o EMF Image Reader, você pode usar o código:
fonte