Java get image extension/type using BufferedImage from URL

后端 未结 4 1212
死守一世寂寞
死守一世寂寞 2020-12-05 13:40

I am familiar with working with images. I retrieve/read an image from a URL, where the URL does not have a file extension. Then I wish to write/save the image to the local s

相关标签:
4条回答
  • 2020-12-05 13:59

    If you get the image from a URL, that means you can access the image through an InputStream. From that you can use ImageIO to get the image type (format) and with the following code, create a BufferedImage at the same time.

    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;
        }
    
      }
    
    0 讨论(0)
  • 2020-12-05 14:02

    Use ImageReader.getFormatName()

    You can get the image readers for a file using ImageIO.getImageReaders(Object input).

    I haven't tested it myself, but you can try this:

    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());
    }
    
    0 讨论(0)
  • 2020-12-05 14:03

    The suggestion to use ImageIO.createImageInputStream(obj) will not work if the object is a URL.

    One alternative is to use the URLConnection.guessContentTypeFromStream(InputStream stream) method. This method guesses the content type by examining the first 12 bytes of a stream.

    One complication with using this method is that it requires the given stream parameter to be mark supported, and the stream returned by java url.openStream() is not mark supported.

    Additionally, if you want to be determine the content type and download the image to a BufferedImage, then it would be preferable if the solution only downloaded the content once (as opposed to making two passes, once to determine the content type and a second time to download the image).

    One solution is to use the PushbackInputStream. The PushbackInputStream can be used to download the first initial bytes to determine content type. The bytes can then be pushed back on the stream so that the ImageIO.read(stream) can read the stream in its entirety.

    Possible solution:

    // 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);
    
    0 讨论(0)
  • 2020-12-05 14:14

    This works by feeding in a URL object (that is an image), and returning a file extension

    It requires an initial download though, to the java tmp directory, and it is then deleted after the ImageReader attempts to get the gather the image type

    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;
    
    
    
    }
    
    0 讨论(0)
提交回复
热议问题