簡體   English   中英

Java使用URL中的BufferedImage獲取圖像擴展名/類型

[英]Java get image extension/type using BufferedImage from URL

我熟悉使用圖像 從URL檢索/讀取圖像 ,其中URL沒有文件擴展名。 然后我希望將圖像寫入/保存到本地存儲,但我必須指定圖像文件擴展名(即JPG,PNG等),我無法通過BufferedImage檢索其擴展名。

有人可以指出它是如何做到的? 任何其他方法都可以。

使用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());
}

如果對象是URL,則使用ImageIO.createImageInputStream(obj)的建議將不起作用。

一種替代方法是使用URLConnection.guessContentTypeFromStream(InputStream流)方法。 此方法通過檢查流的前12個字節來猜測內容類型。

使用此方法的一個復雜因素是它需要標記支持給定的流參數,並且不支持java url.openStream()返回的流。

另外,如果你想確定內容類型並將圖像下載到BufferedImage,那么最好是解決方案只下載一次內容(而不是兩次通過,一次確定內容類型,第二次下載圖片)。

一種解決方案是使用PushbackInputStream。 PushbackInputStream可用於下載第一個初始字節以確定內容類型。 然后可以在流上推回字節,以便ImageIO.read(流)可以完整地讀取流。

可能的方法:

// 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);

如果從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;
    }

  }

這通過輸入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;



}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM