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