How do you clone a BufferedImage
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, bu开发者_开发百科t these new images may be altered and i don't want the original object images to be altered by altering the new objects images.
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.
I just want to be able to get a fresh entirely separate copy or clone of a BufferedImage
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);
}
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.
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);
}
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.
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;
}
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)
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
The following solution using arraycopy is about 3-4 times faster than the accepted answer:
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;
}
By the way, the answers using Graphics2D provide similarly good results.
Here is a solution I wrote many years ago for JFreeChart.
It will also copy any Properties which may be present in the BufferedImage.
I believe it was tested with all known Colour Models (Image Types).
Whether it will work with Image Type 0
discussed by @JoséRobertoAraújoJúnior I don't know.
But: Image Type 0 is invalid & should not occur.
/**
* Copied from
* <a href=https://github.com/jfree/jfreechart/blob/master/src/main/java/org/jfree/chart/util/PaintAlpha.java>JFreeChart PaintAlpha</a>
*
* @param srcImage
* @return
*/
public static BufferedImage cloneImage(final BufferedImage srcImage) {
final WritableRaster srcRaster = srcImage.getRaster();
final WritableRaster dstRaster = srcRaster.createCompatibleWritableRaster();
/*
* This is the code that actually COPIES the pixels...
*/
dstRaster.setRect(srcRaster);
/*
* Images hardly ever have Properties, but we copy them anyway...
*/
final String[] propNames = srcImage.getPropertyNames();
final Hashtable<String, Object> props;
if (propNames == null) {
props = null;
} else {
props = new Hashtable<>();
for (int i = 0; i < propNames.length; i++) {
props.put(propNames[i], srcImage.getProperty(propNames[i]));
}
}
/*
* That's it folks! Return the new clone...
*/
return new BufferedImage(srcImage.getColorModel(), dstRaster, srcImage.isAlphaPremultiplied(), props);
}
I have made this solution using two functions it works on every possible image, even image by camcorder of laptop, I was facing problem that after croping image through camera it was not working but this solution will work
static BufferedImage deepCopy(BufferedImage bi)
{
try
{
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster());
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
catch(Exception ex)
{
}
try{
BufferedImage b = new BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
Graphics g = b.getGraphics();
g.drawImage(bi, 0, 0, null);
g.dispose();
return b;
}
catch(Exception ex){
}
return null;
}
精彩评论