Как клонировать BufferedImage

У меня есть объект, в котором есть много bufferedimages, я хочу создать новый объект, копирующий все буферизированные изображения в новый объект, но эти новые изображения могут быть изменены, и я не хочу, чтобы исходные изображения объектов изменялись, изменяя новые объекты.

это ясно?

Можно ли это сделать, и может ли кто-нибудь предложить хороший способ сделать это, пожалуйста? Я думал о 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); } 

Я делаю это:

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

Класс BufferedImage не реализует интерфейс Cloneable. Таким образом, метод клона не переоценивается. Вот альтернатива для метода глубокой копии: Java Tip 76: альтернатива методу глубокой копии

Другой способ – использовать class 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; } 

Это было безумно полезно для программы, которую я использую, чтобы рисовать вещи, и не смог реализовать Undo / Redo из-за того, что BufferedImages на стеках был практически одним и тем же.

Кстати, я предлагаю полностью использовать пару стеков для этих операций! Каждый раз, когда вы что-то делаете, сразу создайте новый образ, используйте метод deepCopy, упомянутый выше

 image = deepCopy((BufferedImage) stackUndo.peek()); 

измените изображение по своему усмотрению, затем, когда вы прекратите редактирование (например, когда вы отпустите кнопку мыши), сделайте

 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)!

Я знаю, что этот вопрос довольно старый, но для будущих посетителей, вот решение, которое я бы использовал:

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

Пожалуйста, исправьте меня, если изменение только что полученного newImage также повлияет на исходное изображение.
-> Javadoc для getScaledInstance
-> Javadoc для SCALE_DEFAULT (остальные константы перечислены чуть ниже этого)

  • Что такое Apache Camel?
  • Разница между Color.red и Color.RED
  • Как изменить цвет конкретных слов в JTextPane?
  • Как я могу форматировать номер строки, чтобы иметь запятые и круглые?
  • Печать с помощью «\ t» (вкладки) не приводит к выравниванию столбцов
  • Планирование задания с помощью Spring программно (с динамическим набором fixedRate)
  • Игнорирование новых полей объектов JSON с использованием Jackson
  • Как работает аннотация «Spring @ResponseBody» в этом примере приложения RESTful?
  • Почему я не могу ссылаться на метод экземпляра при явном вызове конструктора?
  • java.lang.IllegalStateException: путь к исполняемому файлу драйвера должен быть задан с помощью свойства webdriver.chrome.driver
  • Hibernate: Как установить значение параметра NULL-запроса в HQL?
  • Interesting Posts

    Что такое fastest children () или find () в jQuery?

    Как создать структуру данных связанного списка в Java?

    Макрос диаграммы, отображающий неправильные метки из непересекающихся видимых строк на отфильтрованном листе

    Пример прослушивателя в Интернете для Android

    Как объединить (объединить) кадры данных (внутренний, внешний, левый, правый)?

    Новые интересные функции C # 4.0

    Найдите K ближайших соседей, начиная с матрицы расстояния

    Процессы Bash – процесс повторной привязки запущен в фоновом режиме

    В чем разница между двумя рабочими процессами? Когда использовать stream кода авторизации?

    Архетип быстрого запуска Джерри-Мавена в Eclipse

    Откройте URL-адрес из Windows Forms

    Как написать javascript на стороне клиента, чтобы получить и проанализировать ответ «chunked» во времени?

    Как скрыть панель инструментов Windows 7 и панель свойств?

    Как удалить файл, содержащий обратную косую черту под именем Windows 7?

    Приближенные алгоритмы сопоставления строк

    Давайте будем гением компьютера.