我有一個有很多bufferedimages的對象,我想創建一個新的對象,將所有的bufferedimages複製到新的對象中,但這些新的圖像可能會被改變,我不想通過改變新的對象圖像來改變原始對象圖像。你如何克隆一個BufferedImage
是否清楚?
這是可能做到的,任何人都可以提出一個好方法嗎? 我想到了getSubImage,但在某處看到,對子圖像的任何更改都會重新選回父圖像。
我只是希望能夠得到一個BufferedImage
我有一個有很多bufferedimages的對象,我想創建一個新的對象,將所有的bufferedimages複製到新的對象中,但這些新的圖像可能會被改變,我不想通過改變新的對象圖像來改變原始對象圖像。你如何克隆一個BufferedImage
是否清楚?
這是可能做到的,任何人都可以提出一個好方法嗎? 我想到了getSubImage,但在某處看到,對子圖像的任何更改都會重新選回父圖像。
我只是希望能夠得到一個BufferedImage
這樣的事情?
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);
}
謝謝使用這一個來複制我的bufferedimage – f1wade 2010-08-20 08:25:04
我也借我的程序=) – BlackSheep 2012-03-10 16:11:59
沒有爲我工作!複製結束了一個像素更寬。 – 2013-10-17 12:07:23
類BufferedImage的一個新的完全獨立的拷貝或克隆沒有實現Cloneable接口。因此克隆方法未被覆蓋。這是一個深層複製技術的替代方案: Java Tip 76: An alternative to the deep copy technique
這對我使用畫東西的程序出奇有用的,由於對堆棧是幾乎同樣的事情BufferedImages無法實現撤銷/重做狀態。
順便說一句,我建議一路使用這些操作的幾個堆棧! 每次你做的事,馬上創建一個新的形象,使用以上
image = deepCopy((BufferedImage) stackUndo.peek());
提到deepcopy的方法改變形象,請你,那麼當你停止編輯(當您鬆開鼠標按鈕等)做
stackUndo.push(image);
,並總是在離開堆棧的頂部
g.drawImage(stackUndo.peek(),x,y,null);
烤漆元素,然後如果你做一些撤銷/重做操作,遵循東西這樣
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();
}
}
一定要始終在左側堆棧留下的東西,因爲它畫將始終使用元素在頂部(PEEK)吧!
我這樣做:
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;
}
它的工作原理相當好,這是簡單易用。
前面提到的過程在應用於子圖像時失敗。這裏是一個更完整的解決方案:
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);
}
另一種方法是使用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;
}
我知道這個問題是很老,但對於未來的遊客,這裏的解決方案,我會使用:
Image oldImage = getImage();
Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT);
請糾正我,如果改變了剛剛獲得的newImage
也影響了原始圖像以任何方式。
- >Javadoc for getScaledInstance
- >Javadoc for SCALE_DEFAULT(其他常數列僅低於一個)
我認爲這實際上不會複製圖像,即如果你改變了原來的縮放willalso改變,但它已經有一段時間了,讓別人肯定地說。 – f1wade 2016-12-14 22:20:00
不能調用'的clone()'方法?或者我錯過了什麼?我對「BufferedImage」類 – 2010-08-18 16:15:27
的克隆只提供了淺拷貝,因此它將包含對緩存圖像的引用;不是他們的副本。 – 2010-08-18 16:19:13
@NoelM,UltimateGobblement:'BufferedImage'不實現'Cloneable','clone()'方法保護訪問。 – Robert 2012-08-20 16:19:01