Java get image extension / type utilisant BufferedImage à partir de L'URL

je suis familier avec travailler avec les images. J' extraire/lire une image à partir D'une URL, où L'URL n'a pas d'extension de fichier. Puis je tiens à écrire/enregistrer l'image à la mémoire locale, mais je dois spécifier l'extension du fichier image (i.e. JPG, PNG, etc.), dont je ne peux récupérer l'extension par le biais du BufferedImage.

pourrait-on s'il vous plaît indiquer comment cela peut être fait? Toute autre méthode de faire.

23
demandé sur Otto Allmendinger 2012-07-12 11:34:01

4 réponses

Utiliser ImageReader.getFormatName ()

Vous pouvez obtenir les lecteurs d'image pour un fichier en utilisant ImageIO.getImageReaders(entrée Objet).

je n'ai pas testé moi-même, mais vous pouvez essayer ceci:

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());
}
27
répondu Otto Allmendinger 2015-04-28 10:44:53

la suggestion D'utiliser ImageIO.createImageInputStream (obj) ne fonctionnera pas si l'objet est une URL.

une alternative est d'utiliser L'URLConnection.guessContentTypeFromStream (InputStream stream) method. Cette méthode devine le type de contenu en examinant les 12 premiers octets d'un flux.

une complication avec l'utilisation de cette méthode est qu'elle exige que le paramètre de flux donné soit mark supporté, et le flux retourné par l'url java.openStream () n'est pas mark soutenu.

En outre, si vous voulez être déterminer le type de contenu et télécharger l'image sur un BufferedImage, alors il serait préférable que la solution n'ait téléchargé le contenu qu'une seule fois (au lieu de faire deux passes, une fois pour déterminer le type de contenu et une seconde fois pour télécharger l'image).

une solution est d'utiliser le PushbackInputStream. Le PushbackInputStream peut être utilisé pour télécharger les premiers octets initiaux pour déterminer le type de contenu. Octet peut ensuite être repoussé sur le flux de sorte que L'ImageIO.read (stream) peut lire le stream dans son intégralité.

solution Possible:

// 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);
12
répondu JohnC 2016-05-23 18:13:39

si vous obtenez l'image à partir D'une URL, cela signifie que vous pouvez accéder à l'image à travers un InputStream. De que vous pouvez utiliser ImageIO pour obtenir le type d'image (format) et avec le code suivant, créer un BufferedImage en même temps.

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;
    }

  }
3
répondu herrtim 2016-04-21 13:23:18

cela fonctionne en alimentant dans un objet URL (c'est-à-dire une image), et en retournant une extension de fichier

il nécessite cependant un téléchargement initial, dans le répertoire java tmp, et il est ensuite supprimé après que L'ImageReader ait essayé d'obtenir le type gather the image

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;



}
2
répondu med116 2015-10-22 16:43:09