How do you clone a BufferedImage

Viewed 64942

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.

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

8 Answers

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