Слияние двух изображений - PullRequest
77 голосов
/ 23 февраля 2010

Мне нужно объединить два изображения (BufferedImage) в Java. Это не было бы проблемой, если бы не было прозрачности. Базовое изображение уже имеет некоторую прозрачность. Я хочу сохранить это как есть и применить к нему «маску», второе изображение. Это второе изображение не имеет непрозрачных пикселей, фактически оно почти полностью прозрачно, просто имеет несколько менее прозрачных пикселей, чтобы создать некий «световой эффект», такой как рефлекс. Важная деталь: я не хочу делать это на экране, с графикой, мне нужно получить BufferedImage с результирующим слиянием.

Кто-нибудь может мне помочь? Спасибо!

ДЕТАЛИ. Объедините два изображения, сохраняя прозрачность. Это то, что мне нужно сделать.

Примечание: эта Установка альфа-маски BufferedImage в Java не делает то, что мне нужно, потому что она плохо обрабатывает два прозрачных изображения - она ​​изменяет прозрачность первого изображения.

Ответы [ 3 ]

171 голосов
/ 23 февраля 2010

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

Image plus overlay

Пример кода (изображения называются «image.png» и «overlay.png»):

File path = ... // base path of the images

// load source images
BufferedImage image = ImageIO.read(new File(path, "image.png"));
BufferedImage overlay = ImageIO.read(new File(path, "overlay.png"));

// create the new image, canvas size is the max. of both image sizes
int w = Math.max(image.getWidth(), overlay.getWidth());
int h = Math.max(image.getHeight(), overlay.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

// paint both images, preserving the alpha channels
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, null);

// Save as new image
ImageIO.write(combined, "PNG", new File(path, "combined.png"));
3 голосов
/ 23 февраля 2010

Не зная больше о том эффекте, который вы пытаетесь достичь, я просто укажу, что вы также можете рисовать прямо на BufferedImage. Поэтому все, что вы можете сделать на экране, вы можете сделать прямо на самом изображении.

Так что, если все, что вам нужно, это нарисовать один поверх другого, это действительно легко. Просто возьмите объект Graphics для базового изображения и нарисуйте другой объект.

Опять же, в зависимости от того, какой именно эффект вы собираетесь получить, это может не сработать. Более подробная информация позволит лучше помочь. Например, является ли это заданием для AlphaComposite, как упоминает другой респондент, или пользовательским ImageOp (или некоторой комбинацией существующих ImageOps).

3 голосов
/ 23 февраля 2010

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

...