이미지를 BufferedImage로 변환하는 Java


82

이미 StackOverflow 에이 링크 와 같은 질문이 있으며 허용되는 답변은 "casting"입니다.

Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;

내 프로그램에서 다음을 시도합니다.

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = (BufferedImage) image;

불행하게도 런타임 오류가 발생합니다.

sun.awt.image.ToolkitImage를 java.awt.image.BufferedImage로 캐스트 할 수 없습니다.

분명히 캐스팅이 작동하지 않습니다.
질문 : Image를 BufferedImage로 변환하는 적절한 방법은 무엇입니까 (또는 거기에 있습니까)?


버퍼링 된 이미지의 크기를 조정하려면 다음을 시도하십시오. [ stackoverflow.com/questions/4216123/… [1] : stackoverflow.com/questions/4216123/…
user902383

7
기록을 위해 그것을 말하는 것은 컴파일러가 아닙니다. 실제로 컴파일 오류가 아닌 런타임 오류가 표시됩니다.
Stephen C

1
당신이 옳습니다. 지적 해 주셔서 감사합니다. 그에 따라 질문을 수정하겠습니다.
Arek Wilk 2012

@ user902383 내 질문에 직접 답변하지 않더라도 훌륭한 솔루션입니다.
Arek Wilk

OP에 작은 것 : 메서드 ImageIO.read(File)BufferedImage서명으로 a 를 반환합니다 . ( 참조 ) 먼저 Image변수에 할당 한 다음 유형으로 캐스팅 할 필요가 없습니다 BufferedImage. 그것은 사람들이 당신의 코드를 읽는 데 혼란을 줄 수 있습니다.
kevinarpe 2013-08-08

답변:


123

A로부터 자바 게임 엔진 :

/**
 * Converts a given Image into a BufferedImage
 *
 * @param img The Image to be converted
 * @return The converted BufferedImage
 */
public static BufferedImage toBufferedImage(Image img)
{
    if (img instanceof BufferedImage)
    {
        return (BufferedImage) img;
    }

    // Create a buffered image with transparency
    BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

    // Draw the image on to the buffered image
    Graphics2D bGr = bimage.createGraphics();
    bGr.drawImage(img, 0, 0, null);
    bGr.dispose();

    // Return the buffered image
    return bimage;
}

6
@SriHarshaChilakapati You shouldn't be worrying about the memory when using Java.Java 애플리케이션의 평균 메모리 소비량으로 볼 때 다른 개발자는 메모리에 대해 조금 걱정하지 않아도됩니다.
토마스 Zato - 분석 재개 모니카

1
@ TomášZato 이미지 데이터의 픽셀 메모리를 재사용하려고 생각하는 C ++ 세계에서 온 것 같았습니다. 내 이전 의견은 GC가 Java에서 처리하므로이 경우 메모리에 대해 걱정할 필요가 없다는 것을 의미합니다.
Sri Harsha Chilakapati

2
@SriHarshaChilakapati 그래서 가비지 수집기는 자원을 소비하지 않습니까? GC는 메모리를 둘러싼 코드 에서만 사용자를 저장합니다 . 하드웨어 제한을 없애지 않습니다.
Andrew Sannier 2015

5
Image아직로드되지 않은 경우에는 작동 하지 않습니다. 왜냐하면 getWidth(null)또는 케이스에서 getHeight(null)반환 될 것입니다-1
Dims

1
BufferedImage.TYPE_INT_RGB내 썸네일의 색상을 올바르게 얻기 위해 ARGB 대신 사용해야 했습니다
Stephanie

20

이를 처리하는 한 가지 방법은 새로운 BufferedImage를 생성하고 그래픽 객체에게 스케일링 된 이미지를 새로운 BufferedImage에 그리도록 지시하는 것입니다.

final float FACTOR  = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = new BufferedImage(scaleX, scaleY, TYPE);
buffered.getGraphics().drawImage(image, 0, 0 , null);

그것은 캐스팅하지 않고 트릭을 수행해야합니다.


2
생성 된 그래픽 인스턴스를 폐기하는 것을 잊지 마십시오
Sri Harsha Chilakapati 2011

"생성 된 그래픽 인터페이스를 폐기"하는 방법은 무엇입니까?
Buffalo

BufferedImage 생성자의 유형이 getScaledInstance의 유형과 일치해야합니까?
Drazen Bjelovuk

아니요, TYPE은 이미지 데이터가 내부적으로 저장되는 방식 인 ARGB 또는 RGBA와 같은 것입니다. 애플리케이션에서 가장 자연스럽게 느껴지는 것을 선택하십시오. BufferedImage를 입력 할 때 그냥 자동 완성 들여다 [자동 완성] 모든 선택 사항을 볼 수 있습니다.
salbeira

3

당신이 돌아와 경우 sun.awt.image.ToolkitImage, 해당 이미지를 주조 한 다음 사용할 수 있습니다 getBufferedImage ()를 를 얻을 BufferedImage.

따라서 캐스팅하는 마지막 코드 줄 대신 다음을 수행하십시오.

BufferedImage buffered = ((ToolkitImage) image).getBufferedImage();

7
1) sun패키지의 클래스를 사용하는 것이 눈살을 찌푸 립니다. Oracle 이외의 JDK에서 사용 가능하다는 보장은 없습니다. 2) 메서드 getBufferedImage()는 버퍼링 된 이미지가 .NET에 의해 내부적으로 생성 된 경우에만 작동합니다 TookitImage. 대부분 (99 %) 그렇지 않으므로 반환 값은 null입니다. 출처 참조
kevinarpe 2013-08-07

3

Kotlin을 사용하는 경우 Sri Harsha Chilakapati가 제안하는 것과 동일한 방식으로 Image에 확장 메서드를 추가 할 수 있습니다.

fun Image.toBufferedImage(): BufferedImage {
    if (this is BufferedImage) {
        return this
    }
    val bufferedImage = BufferedImage(this.getWidth(null), this.getHeight(null), BufferedImage.TYPE_INT_ARGB)

    val graphics2D = bufferedImage.createGraphics()
    graphics2D.drawImage(this, 0, 0, null)
    graphics2D.dispose()

    return bufferedImage
}

다음과 같이 사용하십시오.

myImage.toBufferedImage()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.