2つの画像をマージする


84

Javaで2つの画像(BufferedImage)をマージする必要があります。透明性がなくても問題ありません。ベース画像にはすでにある程度の透明度があります。これをそのままにして、2番目の画像である「マスク」を適用したいと思います。この2番目の画像には不透明なピクセルがなく、実際にはほぼ完全に透明で、反射のようなある種の「光の効果」を与えるために透明度の低いピクセルがいくつかあります。重要な詳細:これを画面上で実行したくないので、グラフィックを使用して、結果のマージでBufferedImageを取得する必要があります。

誰か助けてもらえますか?ありがとう!

詳細:透明度を維持しながら2つの画像をマージします。これが私がしなければならないことです。

注:JavaのこのSet BufferedImageアルファマスクは、透明度のある2つの画像を適切に処理できないため、必要な処理を実行しません。最初の画像の透明度を変更します。

回答:


179

透明度のある新しいBufferedImageを作成し、他の2つの画像(完全または半透明度)をペイントするだけです。これはどのように見えるかです:

画像とオーバーレイ

サンプルコード(画像は「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"));

2番目の画像を最初の画像の中央に配置する方法はありますか?
アーメド

6
g.dispose();を呼び出すべきではありません。最後に?
m-szalik 2013

こんにちは、私はこのアプローチに続き、第2の画像だけではなく、最初の画像を保存...ここにすべてのヘルプは..いただければ幸い
TP_JAVA

@Peter結合されたファイルをjpegファイルとして右に移動すると、画像がグレー表示されます。助けてください
モハメッドシェビン2017年

3

具体的な答えは出せませんが、ここのjava.awt.AlphaCompositeはあなたの友達です。2つの画像をどのようにマージするかを完全に制御できます。ただし、使用するのは簡単ではありません。最初にグラフィック理論を少し学ぶ必要があります。


3

あなたが達成しようとしている効果についてもっと知らなくても、BufferedImageに直接描画することもできることを指摘しておきます。つまり、画面上でできることはすべて、画像自体で直接行うことができます。

したがって、必要なのが一方を他方の上に描画することだけであれば、それは本当に簡単です。ベースイメージのGraphicsオブジェクトを取得し、もう一方をその上に描画するだけです。

繰り返しますが、目的の正確な効果によっては、機能しない場合があります。詳細が多いほど、より良いヘルプが得られます。たとえば、これは他のレスポンダーが言及しているAlphaCompositeの仕事ですか、それともカスタムImageOp(または既存のImageOpsの組み合わせ)ですか。


1

任意のタイプのファイルを垂直方向にマージします。

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);
        }
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.