你如何克隆BufferedImage

f1w*_*ade 113 java bufferedimage clone copy

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

明白了吗?

这可能吗,有人可以建议一个好方法吗?我已经想到了getSubImage,但是在某处读取子图像的任何更改都会被重新选回父图像.

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

Kla*_*ark 168

像这样的东西?

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这在大多数情况下都有效,但是当裁剪BufferedImage时它会无法正常工作(它会在裁剪之前返回整个图像).对此的一个简单修复是将最后一行更改为: (7认同)
  • 我也在我的程序中借这个=) (3认同)
  • 返回new BufferedImage(cm,raster,isAlphaPremultiplied,null).getSubimage(0,0,bi.getWidth(),bi.getHeight()); (3认同)
  • 谢谢我用这个来复制我的bufferedimage (2认同)

APe*_*son 42

我这样做:

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;
}
Run Code Online (Sandbox Code Playgroud)

它工作得很好,使用起来很简单.

  • 替换图形g = b.getGraphics(); 通过Graphics2D g = b.createGraphics(); 它很完美 (3认同)
  • 这看起来很简单.为什么这不是最好的答案?有一个我不知道的缺陷吗? (2认同)
  • @WVrock如果图像类型为0(自定义)则不起作用 (2认同)

use*_*755 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);
}
Run Code Online (Sandbox Code Playgroud)


Hyp*_*ino 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;
}
Run Code Online (Sandbox Code Playgroud)


Pix*_*ter 5

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

Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);
Run Code Online (Sandbox Code Playgroud)

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

  • 这实际上复制了图像,因为对原始图像的更改不会更改副本。这个答案简短明了,甚至不限于 BufferedImages。唯一的问题是它返回“Image”,而不是“BufferedImage”。 (2认同)