Zwei Bilder zusammenführen

82

Ich muss zwei Bilder (BufferedImage) in Java zusammenführen. Es wäre kein Problem, wenn es keine Transparenz gäbe. Das Basisbild hat bereits eine gewisse Transparenz. Ich möchte das so lassen wie es ist und eine "Maske" darauf anwenden, das zweite Bild. Dieses zweite Bild hat keine undurchsichtigen Pixel, tatsächlich ist es fast vollständig transparent, es hat nur einige weniger transparente Pixel, um eine Art "Lichteffekt" wie einen Reflex zu erzeugen. Wichtiges Detail: Ich möchte dies nicht auf dem Bildschirm tun. Bei Grafiken muss ein BufferedImage mit der resultierenden Zusammenführung abgerufen werden.

Kann mir jemand helfen? Vielen Dank!

DETAILS: Führen Sie zwei Bilder zusammen, um die Transparenz zu gewährleisten. Das muss ich tun.

Hinweis: Diese Set BufferedImage-Alphamaske in Java macht nicht das, was ich brauche, da sie mit den beiden Bildern mit Transparenz nicht gut zurechtkommt - sie ändert die Transparenz des ersten Bildes.

GuilhermeA
quelle

Antworten:

178

Erstellen Sie einfach ein neues BufferedImage mit Transparenz und malen Sie dann die beiden anderen Bilder (mit Voll- oder Halbtransparenz) darauf. So wird es aussehen:

Bild plus Überlagerung

Beispielcode (Bilder heißen 'image.png' und '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"));
Peter Walser
quelle
Gibt es eine Möglichkeit, das zweite Bild in der Mitte des ersten zu haben?
Ahmed
6
Sollten Sie nicht g.dispose () aufrufen? Am Ende?
m-szalik
Hallo, ich folgte diesem Ansatz und speicherte nur das zweite Bild, aber nicht das erste Bild ... Jede Hilfe hier wäre dankbar ..
TP_JAVA
@Peter Das Bild wird ausgegraut, wenn ich die kombinierte Datei als JPEG-Datei korrigiere. Bitte helfen Sie
Mohammed shebin
3

Ich kann Ihnen keine konkrete Antwort geben, aber java.awt.AlphaComposite hier ist Ihr Freund. Sie haben die absolute Kontrolle darüber, wie die beiden Bilder zusammengeführt werden sollen. Die Verwendung ist jedoch nicht einfach - Sie müssen zuerst ein wenig Grafiktheorie lernen.

Steve McLeod
quelle
3

Ohne mehr über den Effekt zu wissen, den Sie erzielen möchten, möchte ich Sie nur darauf hinweisen, dass Sie auch direkt auf ein BufferedImage zurückgreifen können. Alles, was Sie auf dem Bildschirm tun können, können Sie direkt auf dem Bild selbst tun.

Wenn Sie also nur eines übereinander zeichnen möchten, ist das ganz einfach. Nehmen Sie einfach das Grafikobjekt für das Basisbild und zeichnen Sie das andere darauf.

Abhängig vom genauen Effekt, den Sie erzielen möchten, funktioniert dies möglicherweise nicht. Mehr Details würden eine bessere Hilfe ermöglichen. Ist dies beispielsweise ein Job für AlphaComposite, wie der andere Responder erwähnt, oder ein benutzerdefiniertes ImageOp (oder eine Kombination vorhandener ImageOps).

PSpeed
quelle
0

Führen Sie jeden Dateityp vertikal zusammen.

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);
        }
    }
Kumar Abhishek
quelle