Java使用URL中的BufferedImage获取图像扩展名/类型

我熟悉图像处理 。 我从URL检索/读取图像 ,其中URL没有文件扩展名。 然后我希望将图像写入/保存到本地存储,但我必须指定图像文件扩展名(即JPG,PNG等),我无法通过BufferedImage检索其扩展名。

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

使用ImageReader.getFormatName()

您可以使用ImageIO.getImageReaders(对象输入)获取文件的图像阅读器。

我自己没有测试过,但你可以尝试这个:

ImageInputStream iis = ImageIO.createImageInputStream(file); Iterator 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 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 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; }