Есть ли другой способ, кроме использования ImageIO.read, для получения высоты и ширины изображения?
Потому что я столкнулся с проблемой, которая блокирует поток.
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)
Эта ошибка возникает только на сервере приложений Sun, поэтому я подозреваю, что это ошибка Sun.
java
javax.imageio
серебро эст
источник
источник
jstack
).Ответы:
Вот что-то очень простое и удобное.
источник
Это переписывание отличного поста @Kay, которое выдает исключение IOException и обеспечивает ранний выход:
Думаю, моя репутация недостаточно высока, чтобы мой вклад можно было считать достойным ответа.
источник
javax.imageio.ImageIO.getImageReadersByMIMEType(mimeType)
если хотите быть уверенным в типе файла?.close()
на стрим перед возвращением? в противном случае вы оставите поток открытымorg.apache.commons.io.FilenameUtils#getExtension
для определения расширения имени файла.Я нашел другой способ прочитать размер изображения (более общий). Вы можете использовать класс ImageIO совместно с ImageReaders. Вот пример кода:
Обратите внимание, что getFileSuffix - это метод, который возвращает расширение пути без "." например, png, jpg и т. д. Пример реализации:
Это решение очень быстрое, поскольку из файла считывается только размер изображения, а не все изображение. Я тестировал его, и нет никакого сравнения с производительностью ImageIO.read. Надеюсь, кому-то это пригодится.
источник
getFileSuffix()
содержит ненужные if, и инициализация с помощьюnull
в этом случае не лучшая идея.ImageIO.read()
Полностью улетучивается , как с точки зрения использования процессорного времени, так и памяти.Я попытался проверить производительность, используя некоторые из перечисленных подходов. Трудно провести тщательный тест, так как на результат влияет множество факторов. Я подготовил две папки, одну с 330 файлами jpg и другую с 330 файлами png. Средний размер файла в обоих случаях составлял 4 МБ. Затем я вызвал getDimension для каждого файла. Каждая реализация метода getDimension и каждый тип изображения тестировались отдельно (отдельный прогон). Вот время выполнения, которое я получил (первое число для jpg, второе число для png):
Очевидно, что некоторые методы загружают весь файл, чтобы получить размеры, в то время как другие получают, просто считывая некоторую информацию заголовка с изображения. Я думаю, что эти числа могут быть полезны, когда производительность приложений критична.
Спасибо всем за вклад в эту ветку - очень полезно.
источник
Вы можете загрузить двоичные данные jpeg в виде файла и самостоятельно проанализировать заголовки jpeg. Тот, который вы ищете, - это заголовок 0xFFC0 или Start of Frame:
Для получения дополнительной информации о заголовках ознакомьтесь с записью jpeg в Википедии, или я получил указанную выше информацию здесь .
Я использовал метод, аналогичный приведенному ниже коду, который я получил из этого сообщения на форумах sun:
}
источник
==192
этого следует проверять номера 192-207, кроме 196, 200 и 204.com.drewnoakes.metadata-extractor
библиотеку, чтобы легко извлечь эти заголовкиПростой способ:
источник
Проблема с ImageIO.read в том, что он очень медленный. Все, что вам нужно сделать, это прочитать заголовок изображения, чтобы узнать его размер.
ImageIO.getImageReader
идеальный кандидат.Вот пример Groovy, но то же самое относится и к Java.
Производительность была такой же, как при использовании java-библиотеки SimpleImageInfo.
https://github.com/cbeust/personal/blob/master/src/main/java/com/beust/SimpleImageInfo.java
источник
getReaderByFormat
?Вы можете использовать Toolkit, без ImageIO
Если вы не хотите обрабатывать загрузку изображения, сделайте
источник
Вы можете получить ширину и высоту изображения с помощью объекта BufferedImage, используя java.
источник
Получение буферизованного изображения с помощью ImageIO.read - очень сложный метод, поскольку он создает полную несжатую копию изображения в памяти. Для png вы также можете использовать pngj и код:
источник
После боролся с
ImageIO
много в последние годы, я думаю , что Эндрю Тейлор «S решение , безусловно , является лучшим компромиссом (быстрый: не используетсяImageIO#read
, и универсальный). Спасибо чувак!!Но я был немного разочарован тем, что вынужден был использовать локальный файл (File / String), особенно в тех случаях, когда вы хотите проверить размеры изображений, исходящие, скажем, из запроса multipart / form-data, из которого вы обычно получаете
InputPart
/InputStream
. Так что я быстро сделал вариант, который принимаетFile
,InputStream
иRandomAccessFile
, исходя из его возможностейImageIO#createImageInputStream
.Конечно, такой метод с
Object input
, может оставаться только частным, и вы должны создать столько полиморфных методов, сколько необходимо, вызывая этот. Вы также можете принятьPath
withPath#toFile()
иURL
withURL#openStream()
до перехода к этому методу:источник
Поэтому, к сожалению, после того, как я попробовал все ответы сверху, я не смог заставить их работать после неустанных попыток. Так что я решил сделать настоящий хакер сам и пошел на это на работу. Я верю, что это сработает и для вас.
Я использую этот простой метод, чтобы получить ширину изображения, созданного приложением, которое еще предстоит загрузить для проверки:
Пожалуйста. обратите внимание: вам нужно будет включить разрешения в манифесте для доступа к хранилищу.
/ Я сделал его статическим и поместил в свой глобальный класс, чтобы я мог ссылаться на него или получать к нему доступ только из одного источника, и если есть какие-либо изменения, все это должно быть сделано только в одном месте. Просто поддержание концепции DRY в java. (в любом случае) :) /
}
источник
Чтобы получить размер файла emf без EMF Image Reader, вы можете использовать код:
источник