Как преобразовать буферизованное изображение в изображение и наоборот? - PullRequest
21 голосов
/ 03 февраля 2012

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

  BufferedImage buffer = ImageIO.read(new File(file));

, в изображение, то есть в формате, подобном следующему:* Можно ли так ??Если да, то как ??

Ответы [ 6 ]

25 голосов
/ 03 февраля 2012

BufferedImage - это (n) изображение, поэтому неявное приведение, которое вы выполняете во второй строке, может быть скомпилировано напрямую. Если бы вы знали, что Image - это действительно BufferedImage, вам бы пришлось привести его в явном виде примерно так:

Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;

Поскольку BufferedImage расширяет Image, он может помещаться в контейнер Image. Тем не менее, любое изображение может туда поместиться, в том числе и те, которые не являются BufferedImage, и поэтому вы можете получить ClassCastException во время выполнения, если тип не соответствует, потому что BufferedImage не может содержать любой другой тип, если он не расширяет BufferedImage.

11 голосов
/ 13 марта 2013

Пример: скажем, у вас есть «изображение», которое вы хотите масштабировать, вам, вероятно, понадобится bufferedImage, и, вероятно, он будет начинаться только с объекта «Изображение».Так что это работает, я думаю ... AVATAR_SIZE - это целевая ширина, которую мы хотим, чтобы наше изображение было:

Image imgData = image.getScaledInstance(Constants.AVATAR_SIZE, -1, Image.SCALE_SMOOTH);     

BufferedImage bufferedImage = new BufferedImage(imgData.getWidth(null), imgData.getHeight(null), BufferedImage.TYPE_INT_RGB);

bufferedImage.getGraphics().drawImage(imgData, 0, 0, null);
8 голосов
/ 03 февраля 2012

BufferedImage является подклассом Изображение .Вам не нужно делать никаких преобразований.

6 голосов
/ 23 марта 2016

Правильный способ - использовать SwingFXUtils.toFXImage(bufferedImage,null) для преобразования BufferedImage в экземпляр изображения JavaFX и SwingFXUtils.fromFXImage(image,null) для обратной операции.

При желании вторым параметром может быть WritableImage, чтобы избежать дальнейшего выделения объекта.

6 голосов
/ 03 февраля 2012

Вы можете попробовать сохранить (или записать) буферизованное изображение с внесенными вами изменениями, а затем открыть его как изображение.

РЕДАКТИРОВАТЬ:

try {
    // Retrieve Image
    BufferedImage buffer = ImageIO.read(new File("old.png"));;
    // Here you can rotate your image as you want (making your magic)
    File outputfile = new File("saved.png");
    ImageIO.write(buffer, "png", outputfile); // Write the Buffered Image into an output file
    Image image  = ImageIO.read(new File("saved.png")); // Opening again as an Image
} catch (IOException e) {
    ...
}
4 голосов
/ 25 февраля 2014

Просто информация: давайте все помним, что класс Image на самом деле является абстрактным классом, и ссылка на переменную этого с помощью BufferedImage только сохраняет или возвращает адрес памяти любого объекта.

Кроме того, поэтому статический метод java.awt.image.imageIO read() возвращает объект BufferedImage, поэтому нет сомнений, что использование оператора / выражения instanceof BufferedImage для этого объекта вернет true.

Фактически, будучи абстрактным, класс Image имеет такие сигнатуры методов, как:

  1. public abstract Graphics getGraphics()
  2. public abstract ImageProducer getSource()

среди других.

Подчеркну, что действительная переменная Image содержит только адрес памяти конкретного объекта подкласса Image, почти как указатели в C, C ++, Ada и т. Д.

Если вы представилисьили продвинутый в этих языках, а также в экземплярах интерфейса Java, таких как Runnable, javax.sound.Clip, AWT Shape и т. д.Обратите внимание, что Image имеет: public abstract Image getScaledInstance(...) - вы получаете очко.(Конечно, масштабирование в программировании 2D-графики взаимозаменяемо с изменением размера, для которого желательна точность).

Но в невозможном случае, когда здесь метод ImageIO возвращает ! (instanceof BufferedImage), просто создайте новый объект BufferedImage с этимImgObjNotInstncfBufImg апассируется одному из аргументов конструктора.Затем at (рациональное) будет манипулировать этим в логике вашего кода.

В любом случае класс Affine Transform подходит для преобразования фигур и изображений в их масштабированные, повернутые, перемещенные и т. Д. Формы, поэтому я рекомендую вамизучить об использовании "аффинного преобразования".

Обратите внимание, что вы можете манипулировать фактическими пикселями в таком растре изображения, а также другом техническом жаргоне 2D-графики, на который следует ссылаться из технического глоссария, - который, возможно, потребует отработанного навыка в Java-методах двоичных слепых операцийв типах буферов изображений, которые хранят отдельные цветовые атрибуты в компактном формате по 32 байта - по 7 бит для значений альфа и RGB.

Я подозреваю, что вы собираетесь использовать его в наложении изображений.Итак, наконец, рационально то, что вы ссылаетесь только на BufferedImage с абстрактным изображением, и если ваш Image объект еще не является BufferedImage, то вы можете просто сделать изображение из этого связанного, но-non-BufferedImage-instance, не беспокоясь о какой-либо конвертации, трансляции, автобоксе или чем-либо еще;манипулирование BufferedImage действительно означает манипулирование также базовым корневым объектом, несущим данные, на который он указывает.

Хорошо, закончил;Я думаю, что я, конечно, извлек и раскололся, в какой тупик вы могли подумать.Как я уже говорил, абстрактные классы в java, а также интерфейсы очень похожи на низкоуровневые операторы, более близкие к аппаратному, называемые указателями в других языках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...