130

多くのバッファリングされた画像を含むオブジェクトがあり、すべてのバッファリングされた画像を新しいオブジェクトにコピーする新しいオブジェクトを作成したいのですが、これらの新しい画像は変更される可能性があり、元のオブジェクトの画像を変更して変更したくありません。新しいオブジェクトの画像。

それは明らかですか?

これを行うことは可能ですか?誰かがそれを行うための良い方法を提案できますか?getSubImageについて考えましたが、サブイメージへの変更が親イメージに反映されることをどこかで読みました。

BufferedImageの完全に別のコピーまたはクローンを取得できるようにしたいだけです。

4

7 に答える 7

181

このようなもの?

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);
}
于 2010-08-18T16:26:15.933 に答える
54

私はこれをします:

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

それはかなりうまく機能し、使い方は簡単です。

于 2013-10-11T21:04:50.950 に答える
24

前述の手順は、サブイメージに適用すると失敗します。より完全な解決策は次のとおりです。

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);
}
于 2014-11-12T19:19:41.273 に答える
5

もう1つの方法は、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;
}
于 2015-07-05T01:37:33.330 に答える
4

この質問はかなり古いことは知っていますが、将来の訪問者のために、私が使用する解決策は次のとおりです。

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

newImage得られたばかりの画像を変更しても元の画像に何らかの影響がある場合は、訂正してください。
-> getScaledInstanceのJavadoc-
> SCALE_DEFAULTのJavadoc(他の定数はそのすぐ下にリストされています)

于 2016-12-14T16:40:31.693 に答える
2

クラスBufferedImageは、Cloneableインターフェースを実装していません。したがって、cloneメソッドはオーバーライドされません。ディープコピー手法の代替案は 次のとおりです。Javaヒント76:ディープコピー手法の代替案

于 2010-08-18T16:21:47.503 に答える
0

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を使用した回答でも同様に良い結果が得られます。

于 2021-03-10T16:55:20.747 に答える