【问题标题】:Merging two images合并两个图像
【发布时间】:2011-01-20 01:18:30
【问题描述】:

我需要在 Java 中合并两个图像 (BufferedImage)。如果没有透明度,那将不是问题。基本图像已经具有一定的透明度。我想保持原样并对其应用“蒙版”,即第二张图像。第二张图片没有不透明的像素,实际上它几乎是完全透明的,只是有一些不太透明的像素来提供某种“光效”,比如反射。重要细节:我不想在屏幕上执行此操作,使用图形,我需要获得一个带有结果合并的 BufferedImage。

谁能帮帮我? 谢谢!

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

注意:这个Set BufferedImage alpha mask in Java 不能满足我的需要,因为它不能很好地处理两个具有透明度的图像 - 它会修改第一张图片的透明度。

【问题讨论】:

    标签: java image-processing transparency alpha


    【解决方案1】:

    只需创建一个具有透明度的新 BufferedImage,然后在其上绘制其他两个图像(全透明或半透明)。 这就是它的样子:

    示例代码(图像称为“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);
    
    g.dispose();
    
    // Save as new image
    ImageIO.write(combined, "PNG", new File(path, "combined.png"));
    

    【讨论】:

    • 有没有办法让第二张图片位于第一张图片的中心?
    • 你不应该调用 g.dispose();最后?
    • 嗨,我遵循了这种方法,只保存了第二张图片,但没有保存第一张图片...这里的任何帮助将不胜感激..
    • @Peter 当我将组合文件设置为 jpeg 文件时,图像变灰。请帮忙
    • @Mohammedshebin 不要使用 jpg,它们是不同的,不要处理透明度
    【解决方案2】:

    我不能给你一个具体的答案,但是这里的 java.awt.AlphaComposite 是你的朋友。您将完全控制您希望这两个图像如何合并。但是它使用起来并不简单——你需要先学习一点图形理论。

    【讨论】:

      【解决方案3】:

      如果不了解您要达到的效果的更多信息,我只想指出您也可以直接在 BufferedImage 上绘图。因此,您可以在屏幕上执行的任何操作都可以直接在图像本身上执行。

      因此,如果您只想将一个绘制在另一个之上,那真的很容易。只需抓住基本图像的 Graphics 对象并将另一个绘制到它上面。

      同样,根据您要达到的确切效果,这可能不起作用。更多细节将提供更好的帮助。例如,这是其他响应者提到的 AlphaComposite 的工作还是自定义 ImageOp(或现有 ImageOps 的某种组合)。

      【讨论】:

        【解决方案4】:

        垂直合并任何类型的文件。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-04-15
          • 2011-04-22
          • 2018-01-19
          • 2012-10-10
          • 2012-02-10
          • 2016-01-19
          • 2011-05-21
          相关资源
          最近更新 更多