如何克隆 BufferedImage

发布于 2024-09-14 18:15:48 字数 217 浏览 7 评论 0原文

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

清楚了吗?

这可以做到吗?有人可以建议一个好方法吗? 我想过 getSubImage 但在某处读到对子图像的任何更改都会反射回父图像。

我只是希望能够获得 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, 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

够钟 2024-09-21 18:15:48

像这样的东西吗?

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

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);
}
盗琴音 2024-09-21 18:15:48

我是这样做的:

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

效果相当好,而且使用起来很简单。

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.

铜锣湾横着走 2024-09-21 18:15:48

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

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

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);
}
猫七 2024-09-21 18:15:48

另一种方法是使用 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;
}

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;
}
扎心 2024-09-21 18:15:48

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

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

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

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)

爱,才寂寞 2024-09-21 18:15:48

BufferedImage 类没有实现 Cloneable 接口。因此克隆方法不会被重写。这是深度复制技术的替代方法:
Java 技巧 76:深度复制技术的替代方法

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

云巢 2024-09-21 18:15:48

使用 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 的答案提供了类似的良好结果。

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.

会傲 2024-09-21 18:15:48

这是我多年前为 JFreeChart 编写的解决方案。

它还将复制 BufferedImage 中可能存在的任何属性。

我相信它已经用所有已知的颜色模型(图像类型)进行了测试。

我不知道它是否适用于@JoséRobertoAraújoJúnior 讨论的Image Type 0
但是: 图像类型 0 无效,并且图像类型 0 无效。不应该发生。

/**
 * 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);
}

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);
}
如梦 2024-09-21 18:15:48

我使用两个函数制作了这个解决方案,它适用于每个可能的图像,甚至是笔记本电脑摄像机拍摄的图像,我面临的问题是,通过相机裁剪图像后,它不起作用,但这个解决方案可以工作

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文