130

我有一个包含许多缓冲图像的对象,我想创建一个新对象,将所有缓冲图像复制到新对象中,但是这些新图像可能会被更改,我不希望通过更改原始对象图像来更改新对象图像。

明白了吗?

这是可能的吗,有人可以提出一个好的方法吗?我想到了 getSubImage,但在某处读到对子图像的任何更改都会被反射回父图像。

我只是希望能够获得 BufferedImage 的全新的完全独立的副本或克隆

4

7 回答 7

181

像这样的东西?

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);
}
于 2010-08-18T16:26:15.933 回答
54

我这样做:

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

它工作得很好,而且使用起来很简单。

于 2013-10-11T21:04:50.950 回答
24

前面提到的过程在应用于子图像时会失败。这是一个更完整的解决方案:

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);
}
于 2014-11-12T19:19:41.273 回答
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;
}
于 2015-07-05T01:37:33.330 回答
4

我知道这个问题已经很老了,但是对于未来的访问者,这是我要使用的解决方案:

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

如果更改刚刚获得newImage的图像也会以任何方式影响原始图像,请纠正我。
-->用于 getScaledInstance 的 Javadoc
-->用于 SCALE_DEFAULT的 Javadoc(其他常量列在该常量的下方)

于 2016-12-14T16:40:31.693 回答
2

类 BufferedImage 不实现 Cloneable 接口。因此,克隆方法不会被覆盖。下面是深拷贝技术的一种替代方法: Java Tip 76: An alternative to the deep copy technology

于 2010-08-18T16:21:47.503 回答
0

以下使用 arraycopy 的解决方案比接受的答案快大约 3-4 倍:

public static BufferedImage copyImage(BufferedImage source){
    BufferedImage bi = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
    byte[] sourceData = ((DataBufferByte)source.getRaster().getDataBuffer()).getData();
    byte[] biData = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
    System.arraycopy(sourceData, 0, biData, 0, sourceData.length);
    return bi;
}

顺便说一句,使用 Graphics2D 的答案提供了同样好的结果。

于 2021-03-10T16:55:20.747 回答