BufferedImage를 어떻게 복제합니까?


120

버퍼링 된 이미지가 많은 개체가 있습니다. 모든 버퍼링 된 이미지를 새 개체에 복사하는 새 개체를 만들고 싶지만 이러한 새 이미지가 변경 될 수 있으며 원본 개체 이미지가 새로운 개체 이미지.

그게 분명해?

이것이 가능합니까? 누구나 좋은 방법을 제안 할 수 있습니까? getSubImage를 생각했지만 하위 이미지의 변경 사항이 부모 이미지로 다시 반영된다는 것을 어딘가에서 읽었습니다.

BufferedImage의 완전히 별도의 복사본 또는 복제본을 얻을 수 있기를 원합니다.


1
clone()메서드 를 호출 할 수 없습니까? 아니면 내가 뭔가를 놓친 적이 있습니까? BufferedImage수업 에 대해 잘 모릅니다
Noel M

1
clone은 얕은 복사본 만 제공하므로 버퍼링 된 이미지에 대한 참조를 포함합니다. 사본이 아닙니다.
Ultimate Gobblement 2010-08-18

7
@NoelM, UltimateGobblement은 : BufferedImage구현하지 않습니다 Cloneableclone()방법은 액세스를 보호하고있다.
Robert

답변:


173

이 같은?

static BufferedImage deepCopy(BufferedImage bi) {
 ColorModel cm = bi.getColorModel();
 boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
 WritableRaster raster = bi.copyData(null);
 return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}

4
나는 또한) = 내 프로그램이 차입하고있어
다니엘 캣츠

서브 이미지 복사에이 방법으로 문제가
mishka을

7
이것은 대부분의 상황에서 작동하지만 BufferedImage가 잘 렸을 때 제대로 작동하지 않습니다 (잘라 내기 전에 전체 이미지를 반환합니다). 이에 대한 간단한 수정은 마지막 줄을 다음과 같이 변경하는 것입니다.
HaydenStudios

3
return new BufferedImage (cm, raster, isAlphaPremultiplied, null) .getSubimage (0, 0, bi.getWidth (), bi.getHeight ());
HaydenStudios 2014-06-29

copyData (null)은 상위 래스터에서 작동 할 수 있기 때문에 항상 작동하지는 않습니다 (예 : 이미지가 하위 이미지 인 경우), 수정 된 답변 참조
user1050755

46

나는 이것을한다:

public static BufferedImage copyImage(BufferedImage source){
    BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
    Graphics g = b.getGraphics();
    g.drawImage(source, 0, 0, null);
    g.dispose();
    return b;
}

상당히 잘 작동하고 사용하기 쉽습니다.


3
이것은 매우 간단 해 보입니다. 이것이 최선의 답이 아닌 이유는 무엇입니까? 내가 알지 못하는 결함이 있습니까?
WVrock

2
이미지 유형이 0 인 경우는 (정의)이 작동하지 않습니다 @WVrock
틸만 하우 쉐어

3
그래픽 교체 g = b.getGraphics (); 작성자 : Graphics2D g = b.createGraphics (); 그것은 완벽
디르

1
나는 이것이 가장 깨끗한 대답이라고 생각합니다. 이것과 허용되는 답변 사이에 성능 차이가 있습니까? 내가 아니라면 무시할 것 같은 느낌? 이것이 순전히 jvm에서 객체 생성이 최적화되는 원인이 될 수 있습니까? 또한 openjdk 11을 사용합니다. 누구든지 그 질문에 답할 수 있다면.
thekevshow

18

이전에 언급 한 절차는 서브 이미지에 적용 할 때 실패합니다. 다음은보다 완벽한 솔루션입니다.

public static BufferedImage deepCopy(BufferedImage bi) {
    ColorModel cm = bi.getColorModel();
    boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
    WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster());
    return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}

감사합니다. 하위 이미지를 복제하는 동안 오프셋 오류가 발생했습니다. 이 버전은 정확히 내가 필요한 것입니다.
로코코

5

또 다른 방법은 Graphics2D클래스 를 사용하여 새 빈 이미지에 이미지를 그리는 것입니다. 이것은 실제로 이미지를 복제하지는 않지만 이미지 사본이 생성됩니다.

public static final BufferedImage clone(BufferedImage image) {
    BufferedImage clone = new BufferedImage(image.getWidth(),
            image.getHeight(), image.getType());
    Graphics2D g2d = clone.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    return clone;
}


4

이 질문이 꽤 오래되었다는 것을 알고 있지만 향후 방문자를 위해 사용할 솔루션은 다음과 같습니다.

Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);

방금 얻은 변경 newImage이 원본 이미지에도 영향을 미치는 경우 수정하십시오 .
-> getScaledInstance 용 Javadoc-
> SCALE_DEFAULT 용 Javadoc (다른 상수는 해당 상수 바로 아래에 나열됩니다)


나는 그것이 실제로 이미지를 복사하지 않을 것이라고 생각합니다. 즉, 원본을 변경하면 배율도 변경되지만 오랜 시간이 지나서 다른 사람이 확실하게 말할 수 있습니다.
f1wade

1
이것은 실제로 이미지를 복사합니다. 원본을 변경해도 사본은 변경되지 않습니다. 이 답변은 짧고 간결하며 BufferedImages에만 국한되지 않습니다. 유일한 문제는 반환이다 Image,하지 BufferedImage.
Kröw
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.