我熟悉使用图像.我从URL检索/读取图像,其中URL没有文件扩展名.然后我希望将图像写入/保存到本地存储,但我必须指定图像文件扩展名(即JPG,PNG等),我无法通过BufferedImage检索其扩展名.
有人可以指出它是如何做到的?任何其他方法都可以.
Ott*_*ger 32
您可以使用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());
}
Joh*_*hnC 16
如果对象是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;
    }
  }