合并两张图片

我需要在 Java 中合并两个映像(BufferedImage)。如果没有透明度就不会有问题。基本图像已经具有一定的透明度。我想保持它的原样,并应用一个“面具”到它,第二个图像。第二张图片没有不透明像素,事实上它几乎是完全透明的,只是有一些不那么透明的像素来产生某种“光效果”,就像反射一样。重要的细节: 我不想在屏幕上进行这项操作,我需要获得一个 BufferedImage,并生成合并结果。

有人能帮我吗? 谢谢!

细节: 合并两个图像以保持透明度。这是我需要做的。

注意: 这个 在 Java 中设置 BufferedImage alpha 掩码不做什么我需要的,因为它不处理好与两个图像有透明度-它修改第一图片透明度。

103508 次浏览

I can't give you a specific answer, but java.awt.AlphaComposite here is your friend. You'll get absolute control over how you want the two images to merge. However it is not straightforward to use - you need to learn a bit of graphics theory first.

Without knowing more about the effect you are trying to achieve, I'll just point out that you can also draw right onto a BufferedImage. So anything you could do on screen you can do right on the image itself.

So if all you want is one drawn on top of the other, that's really easy. Just grab the Graphics object for the base image and draw the other onto it.

Again, depending on the exact effect you are going for that may not work. More detail would allow better help. For example, is this a job for AlphaComposite as the other responder mentions or a custom ImageOp (or some combination of existing ImageOps).

Just create a new BufferedImage with transparency, then paint the other two images (with full or semi-transparency) on it. This is how it will look like:

Image plus overlay

Sample code (images are called 'image.png' and '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);


g.dispose();


// Save as new image
ImageIO.write(combined, "PNG", new File(path, "combined.png"));

merge any type of file vertically.

void mergeFiles(List<String> files, String fileName) {
int heightTotal = 0;
int maxWidth = 100;


List<BufferedImage> images = new ArrayList<>();
try {
for (String file : files) {
BufferedImage image = ImageIO.read(new File(file));
images.add(image);
}




for (BufferedImage bufferedImage : images) {
heightTotal += bufferedImage.getHeight();
if (bufferedImage.getWidth() > maxWidth) {
maxWidth = bufferedImage.getWidth();
}
}




int heightCurr = 0;
BufferedImage concatImage = new BufferedImage(maxWidth, heightTotal, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = concatImage.createGraphics();
for (BufferedImage bufferedImage : images) {
g2d.drawImage(bufferedImage, 0, heightCurr, null);
heightCurr += bufferedImage.getHeight();
}


File compressedImageFile = new File(fileName);
OutputStream outputStream = new FileOutputStream(compressedImageFile);


float imageQuality = 0.7f;
Iterator<ImageWriter> imageWriters = ImageIO.getImageWritersByFormatName("jpeg");


if (!imageWriters.hasNext())
throw new IllegalStateException("Writers Not Found!!");


ImageWriter imageWriter = imageWriters.next();
ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputStream);
imageWriter.setOutput(imageOutputStream);


ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();


//Set the compress quality metrics
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(imageQuality);


//Created image
imageWriter.write(null, new IIOImage(concatImage, null, null), imageWriteParam);


// close all streams
outputStream.close();
imageOutputStream.close();
imageWriter.dispose();
log.info(" Files Merged");
} catch (IOException e) {
log.error("Error while merging files :::"+e);
throw new RuntimeException(e);
}
}