read JAVA URL에서 버퍼드 이미지를 사용하여 이미지 확장/유형을 가져옵니다.



java imageio write supported formats (4)

나는 이미지 작업에 익숙하다. URL 에서 파일 확장명이없는 이미지를 검색 / 읽습니다 . 그런 다음 이미지 를 로컬 저장소에 쓰거나 저장하고 싶지만 BufferedImage를 통해 해당 확장명을 가져올 수없는 이미지 파일 확장명 (예 : JPG, PNG 등)을 지정해야합니다.

어떻게 할 수 있는지 지적 해주십시오. 다른 방법으로도 가능합니다.

https://src-bin.com


Answer #1

이 작업은 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;



}

Answer #2

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

  }

Answer #3

개체가 URL 인 경우 ImageIO.createImageInputStream (obj)을 사용하라는 제안은 작동하지 않습니다.

한 가지 대안은 URLConnection.guessContentTypeFromStream (InputStream stream) 메소드를 사용하는 것입니다. 이 메서드는 스트림의 처음 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);

Answer #4

ImageReader.getFormatName()

ImageIO.getImageReaders (Object input)를 사용하여 파일의 이미지 리더를 가져올 수 있습니다.

나는 그것을 직접 테스트하지 않았지만 이것을 시도 할 수있다 :

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




image