Подтвердить что ты не робот

Java получает расширение/тип изображения, используя BufferedImage из URL

Я знаком с работой с изображениями. Я получаю /считываю изображение с URL-адреса, где URL-адрес не имеет расширения файла. Затем я хочу записать/сохранить изображение в локальном хранилище, но мне нужно указать расширение файла изображения (т.е. JPG, PNG и т.д.), Которое я не могу получить с помощью BufferedImage.

Можно ли указать, как это можно сделать? Подойдет любой другой метод.

4b9b3361

Ответ 1

Используйте ImageReader.getFormatName()

Вы можете получить считыватели изображений для файла, используя ImageIO.getImageReaders(ввод объекта).

Я не тестировал его сам, но вы можете попробовать следующее:

ImageInputStream iis = ImageIO.createImageInputStream(file);

Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);

while (imageReaders.hasNext()) {
    ImageReader reader = (ImageReader) imageReaders.next();
    System.out.printf("formatName: %s%n", reader.getFormatName());
}

Ответ 2

Предложение использовать ImageIO.createImageInputStream(obj) не будет работать, если объект является URL-адресом.

Один из вариантов заключается в использовании метода URLConnection.guessContentTypeFromStream(InputStream stream). Этот метод угадывает тип содержимого, исследуя первые 12 байтов потока.

Одним из осложнений с использованием этого метода является то, что он требует, чтобы данный параметр потока поддерживался меткой, а поток, возвращаемый java url.openStream(), не поддерживается.

Кроме того, если вы хотите определить тип контента и загрузить изображение в BufferedImage, тогда было бы предпочтительнее, если бы решение только загрузило контент один раз (в отличие от двух проходов, один раз для определения типа контента и второй раз, чтобы загрузить изображение).

Одним из решений является использование PushbackInputStream. PushbackInputStream может использоваться для загрузки первых начальных байтов для определения типа контента. Затем байты могут быть возвращены в поток, чтобы ImageIO.read(stream) мог полностью прочитать поток.

Возможное решение:

// URLConnection.guessContentTypeFromStream only needs the first 12 bytes, but
// just to be safe from future java api enhancements, we'll use a larger number
int pushbackLimit = 100;
InputStream urlStream = url.openStream();
PushbackInputStream pushUrlStream = new PushbackInputStream(urlStream, pushbackLimit);
byte [] firstBytes = new byte[pushbackLimit];
// download the first initial bytes into a byte array, which we will later pass to 
// URLConnection.guessContentTypeFromStream  
pushUrlStream.read(firstBytes);
// push the bytes back onto the PushbackInputStream so that the stream can be read 
// by ImageIO reader in its entirety
pushUrlStream.unread(firstBytes);

String imageType = null;
// Pass the initial bytes to URLConnection.guessContentTypeFromStream in the form of a
// ByteArrayInputStream, which is mark supported.
ByteArrayInputStream bais = new ByteArrayInputStream(firstBytes);
String mimeType = URLConnection.guessContentTypeFromStream(bais);
if (mimeType.startsWith("image/"))
    imageType = mimeType.substring("image/".length());
// else handle failure here

// read in image
BufferedImage inputImage = ImageIO.read(pushUrlStream);

Ответ 3

Если вы получаете изображение с URL-адреса, это означает, что вы можете получить доступ к изображению через InputStream. Из этого вы можете использовать ImageIO, чтобы получить тип изображения (формат) и со следующим кодом, одновременно создайте BufferedImage.

public static BufferedImageWrapper getImageAndTypeFromInputStream(InputStream is) {

    String format = null;
    BufferedImage bufferedimage = null;
    try (ImageInputStream iis = ImageIO.createImageInputStream(is);) {

      Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);

      if (readers.hasNext()) {

        ImageReader reader = readers.next();
        format = reader.getFormatName();
        reader.setInput(iis);
        bufferedimage = reader.read(0);
      }
    } catch (IOException e) {
      logger.error("ERROR DETERMINING IMAGE TYPE!!!", e);
    }

    return new BufferedImageWrapper(format, bufferedimage);
  }

  public static class BufferedImageWrapper {

    private final String imageType;
    private final BufferedImage bufferedimage;

    /**
     * Constructor
     *
     * @param imageType
     * @param bufferedimage
     */
    public BufferedImageWrapper(String imageType, BufferedImage bufferedimage) {
      this.imageType = imageType;
      this.bufferedimage = bufferedimage;
    }

    public String getImageType() {

      return imageType;
    }

    public BufferedImage getBufferedimage() {

      return bufferedimage;
    }

  }

Ответ 4

Это работает путем подачи URL-адреса (то есть изображения) и возврата расширения файла

Требуется первоначальная загрузка, но в каталог java tmp, и она будет удалена после того, как ImageReader попытается собрать тип изображения

public String getImageFileExtFromUrl(URL urlObject) throws URISyntaxException, IOException{
    System.out.println("IN DOWNLOAD FILE FROM URL METHOD");
    String tmpFolder = System.getProperty("java.io.tmpdir");
    String tmpFileStr = tmpFolder + "/" + new Date().getTime();
    Files.copy(urlObject.openStream(), Paths.get(tmpFileStr), StandardCopyOption.REPLACE_EXISTING);
    File download = new File(tmpFileStr);
    System.out.println("FILE DOWNLOAD EXISTS: " + download.exists() );
    try{
        ImageInputStream iis = ImageIO.createImageInputStream(download);
        Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);

        ImageReader reader = iter.next();
        String formatName = reader.getFormatName();
        System.out.println("FOUND IMAGE FORMAT :" + formatName);
        iis.close();
        return formatName;
    }catch(Exception e){
        e.printStackTrace();
    }finally{
        Files.delete(Paths.get(tmpFileStr));
    }
    return null;



}