I have an object which has many bufferedimages in it, I want to create a new object copying all the bufferedimages into the new object, but these new images may be altered and i don't want the original object images to be altered by altering the new objects images.
我有一个对象,其中有许多bufferedimages,我想创建一个新的对象将所有bufferedimages复制到新对象,但这些新图像可能会被更改,我不希望通过更改原始对象图像来改变新物体图像。
is that clear?
明白了吗?
Is this possible to do and can anyone suggest a good way to do it please? I have thought of getSubImage but read somewhere that any changes to the subimage are relected back to the parent image.
这可能吗,有人可以建议一个好方法吗?我已经想到了getSubImage,但是在某处读取了对子图像的任何更改都被重新选回到父图像。
I just want to be able to get a fresh entirely separate copy or clone of a BufferedImage
我只是希望能够获得一个新的完全独立的BufferedImage副本或克隆
7 个解决方案
#1
152
Something like this?
像这样的东西?
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);
}
#2
37
I do this:
我这样做:
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;
}
It works fairly well and it is simple to use.
它工作得很好,使用起来很简单。
#3
15
The previously mentioned procedure fails when applied to sub images. Here is a more complete solution:
应用于子图像时,前面提到的过程失败。这是一个更完整的解决方案:
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);
}
#4
4
Class BufferedImage does not implement the Cloneable interface. Thus the clone method is not overriden. Here's an alternative for a deep copy technique: Java Tip 76: An alternative to the deep copy technique
BufferedImage类不实现Cloneable接口。因此克隆方法不会被覆盖。这是深度复制技术的替代方案:Java技巧76:深度复制技术的替代方案
#5
3
Another way is to use the Graphics2D
class to draw the image onto a new blank image. This doesn't really clone the image, but it results in a copy of the image being produced.
另一种方法是使用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;
}
#6
2
This was insanely useful for a program that I'm using to draw stuff, and was unable to implement Undo/Redo states due to BufferedImages on the Stacks being virtually the same thing.
这对于我用来绘制内容的程序非常有用,并且由于Stacks上的BufferedImages实际上是相同的东西而无法实现Undo / Redo状态。
By the way, I suggest all the way using a couple of stacks for these kind of operations! Everytime you do something, immediately create a new image, use the deepCopy method mentioned above
顺便说一句,我建议使用几个堆栈进行这些操作!每次执行某些操作时,立即创建新图像,使用上面提到的deepCopy方法
image = deepCopy((BufferedImage) stackUndo.peek());
alter the image as you please, then when you stop editing (like when you release the mouse button) do
随你改变图像,然后当你停止编辑时(比如当你松开鼠标按钮时)
stackUndo.push(image);
and always paint the element at the top of the left stack
并始终将元素绘制在左侧堆栈的顶部
g.drawImage(stackUndo.peek(),x,y,null);
and then if you do some undo/redo operation, follow something like this
然后如果你做一些撤消/重做操作,请按照这样的方法
public void undoOrRedo(String op) {
if(op.equals("undo") && stackUndo.size()>1){
stackRedo.push(stackUndo.pop());
repaint();
}
if(op.equals("redo") && stackRedo.size()>0){
stackUndo.push(stackRedo.pop());
repaint();
}
}
be sure to always left something in the left stack, because for painting it will always use the element at the top (peek) of it!
一定要在左侧堆栈中留下一些东西,因为对于绘画,它总是会使用它顶部的元素(窥视)!
#7
1
I know that this question is pretty old, but for future visitors, here's the solution I'd use:
我知道这个问题很老了,但对于未来的访问者来说,这是我使用的解决方案:
Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);
Please correct me if changing the just obtained newImage
also affects the original image in any way.
--> Javadoc for getScaledInstance
--> Javadoc for SCALE_DEFAULT (the other constants are listed just below that one)
如果更改刚刚获得的newImage也会以任何方式影响原始图像,请更正我。 - > Javadoc for getScaledInstance - > Javadoc for SCALE_DEFAULT(其他常量列在那个下面)
#1
152
Something like this?
像这样的东西?
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);
}
#2
37
I do this:
我这样做:
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;
}
It works fairly well and it is simple to use.
它工作得很好,使用起来很简单。
#3
15
The previously mentioned procedure fails when applied to sub images. Here is a more complete solution:
应用于子图像时,前面提到的过程失败。这是一个更完整的解决方案:
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);
}
#4
4
Class BufferedImage does not implement the Cloneable interface. Thus the clone method is not overriden. Here's an alternative for a deep copy technique: Java Tip 76: An alternative to the deep copy technique
BufferedImage类不实现Cloneable接口。因此克隆方法不会被覆盖。这是深度复制技术的替代方案:Java技巧76:深度复制技术的替代方案
#5
3
Another way is to use the Graphics2D
class to draw the image onto a new blank image. This doesn't really clone the image, but it results in a copy of the image being produced.
另一种方法是使用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;
}
#6
2
This was insanely useful for a program that I'm using to draw stuff, and was unable to implement Undo/Redo states due to BufferedImages on the Stacks being virtually the same thing.
这对于我用来绘制内容的程序非常有用,并且由于Stacks上的BufferedImages实际上是相同的东西而无法实现Undo / Redo状态。
By the way, I suggest all the way using a couple of stacks for these kind of operations! Everytime you do something, immediately create a new image, use the deepCopy method mentioned above
顺便说一句,我建议使用几个堆栈进行这些操作!每次执行某些操作时,立即创建新图像,使用上面提到的deepCopy方法
image = deepCopy((BufferedImage) stackUndo.peek());
alter the image as you please, then when you stop editing (like when you release the mouse button) do
随你改变图像,然后当你停止编辑时(比如当你松开鼠标按钮时)
stackUndo.push(image);
and always paint the element at the top of the left stack
并始终将元素绘制在左侧堆栈的顶部
g.drawImage(stackUndo.peek(),x,y,null);
and then if you do some undo/redo operation, follow something like this
然后如果你做一些撤消/重做操作,请按照这样的方法
public void undoOrRedo(String op) {
if(op.equals("undo") && stackUndo.size()>1){
stackRedo.push(stackUndo.pop());
repaint();
}
if(op.equals("redo") && stackRedo.size()>0){
stackUndo.push(stackRedo.pop());
repaint();
}
}
be sure to always left something in the left stack, because for painting it will always use the element at the top (peek) of it!
一定要在左侧堆栈中留下一些东西,因为对于绘画,它总是会使用它顶部的元素(窥视)!
#7
1
I know that this question is pretty old, but for future visitors, here's the solution I'd use:
我知道这个问题很老了,但对于未来的访问者来说,这是我使用的解决方案:
Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);
Please correct me if changing the just obtained newImage
also affects the original image in any way.
--> Javadoc for getScaledInstance
--> Javadoc for SCALE_DEFAULT (the other constants are listed just below that one)
如果更改刚刚获得的newImage也会以任何方式影响原始图像,请更正我。 - > Javadoc for getScaledInstance - > Javadoc for SCALE_DEFAULT(其他常量列在那个下面)