Java Объединение нескольких изображений в одно изображение большего размера без перекрытия

Я пытаюсь объединить несколько изображений в более крупное изображение с помощью Java. Все изображения, которые передаются, имеют высоту 127 x ширину 293. Идея состоит в том, что несколько изображений передаются методу, и метод берет изображения и встраивает их в другое изображение большего размера. Будет макет для большего изображения, в котором всего 12 возможных изображений могут быть введены в большее изображение, равномерно распределенные (2 ряда по 6 изображений, ни одно не перекрывается). Если передано менее 12 изображений, то будет заполнено только первое, сколько бы пробелов ни было, остальная часть изображения будет белой, потому что фон должен быть белым. Когда я запускаю программу, она печатает увеличенное изображение, но оно заполняет только первое пространство, показывая первое изображение в левом верхнем углу, независимо от того, сколько изображений передано. Также фон имеет розоватый цвет вместо предполагаемого белого фона. . Я только новичок в Java, поэтому я пытаюсь справиться с некоторыми из этих трудностей обучения. Любые советы о том, как я мог бы быть в состоянии решить мою проблему? (Код скопирован ниже для справки) Спасибо!

public class ImagesCombine {

public String BuildImgs (File[] imgs)throws IOException {
    int arsize = imgs.length;
    File path = new File("Z:/JAVAFiles/Images/");
    BufferedImage page = new BufferedImage(620,900,BufferedImage.TYPE_INT_ARGB);
    Graphics2D paint;
    paint = page.createGraphics();
    paint.setPaint(Color.WHITE);
    paint.fillRect ( 0, 0, page.getWidth(), page.getHeight() ); 
    paint.setBackground(Color.WHITE);
    String tmpname = "";

    for (int i=0;i<imgs.length;i++){

        if(i==0){ 
            Image img0 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img0,0,0,null);
            paint.dispose();
            }
        if(i==1){
            Image img1 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img1,323,0,null);
            paint.dispose();
            }
        if(i==2){
            Image img2 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img2,0,142,null);
            paint.dispose();
            }
        if(i==3){
            BufferedImage img3 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img3,323,142,null);
            paint.dispose();
            }
        if(i==4){
            BufferedImage img4 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img4,0,284,null);
            paint.dispose();
            }
        if(i==5){
            BufferedImage img5 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img5,323,284,null);
            paint.dispose();
            }
        if(i==6){
            BufferedImage img6 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img6,0,426,null);
            paint.dispose();
            }
        if(i==7){
            BufferedImage img7 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img7,323,426,null);
            paint.dispose();
            }
        if(i==8){
            BufferedImage img8 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img8,0,568,null);
            paint.dispose();
            }
        if(i==9){
            BufferedImage img9 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img9,323,568,null);
            paint.dispose();
            }
        if(i==10){
            BufferedImage img10 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img10,0,710,null);
            paint.dispose();
            }
        if(i==11){
            BufferedImage img11 = ImageIO.read(new File(path, imgs[i].getName()));
            paint.drawImage(img11,323,710,null);
            paint.dispose();
            }

        }
    String outpath = "Z:\\JAVAFiles\\" + imgs[0].getName().substring(0,16) + ".jpg";

    OutputStream outfile = new FileOutputStream(outpath);

    JPEGImageEncoder encoder2 = JPEGCodec.createJPEGEncoder(outfile);
    encoder2.encode(page);
    outfile.close();
    return("Success");  
}
}

person tab2006    schedule 20.07.2011    source источник
comment
Я заметил, что вы используете тип изображения для первых трех изображений, но тип буферизованного изображения для всех остальных. Это делается по какой-то конкретной причине?   -  person Eternal_Light    schedule 21.07.2011


Ответы (4)


Первое, что я заметил, это то, что вы вызываете dispose() для Graphics2D после каждого отрисовки изображения. Вероятно, поэтому вы видите только одно изображение, нарисованное на большом изображении. Выньте этот вызов и поместите его после цикла, и вы должны начать видеть больше изображений.

В качестве примечания, вы можете значительно упростить цикл for:

int width = 293;
int height = 127;
for (int i=0; i < Math.min(imgs.length, 12); i++){
    Image image = ImageIO.read(new File(path, imgs[i].getName()));
    int row = i / 6; // This will truncate to 0 or 1.
    int column = i % 6; // Mod will produce the remainder of i / 6 in the range 0-5
    paint.drawImage(image, column * width, row * height, null);
}
person Kainsin    schedule 20.07.2011
comment
Я избавился от dispose(), но по-прежнему получаю только одно изображение в левом верхнем углу (1-е место в моем макете). Однако цикл for был отличным советом. Я знал, что есть способ упростить это, просто не мог толком обдумать это. Спасибо! - person tab2006; 21.07.2011
comment
Получаете ли вы какие-либо исключения при запуске этого метода? Вы можете попробовать другой способ сохранения изображения с помощью ImageIO.write(page, "JPG", new File(outpath)); - person Kainsin; 21.07.2011

Вы вызываете метод dispose внутри цикла for, поэтому, когда программа завершает первый запуск кода внутри цикла, она избавляется от объекта рисования. Когда пришло время просмотреть цикл во второй раз, программа не может найти объект краски, поэтому она не может ни нарисовать следующее изображение, ни заполнить комнату белым цветом.

Попробуйте использовать метод dispose сразу после закрытия цикла for.

Вы также можете попробовать добавить некоторые методы println, чтобы узнать, какую длину возвращает элемент imgs. Как правило, вы должны проверять числа внутри переменных, которые вы используете в своем цикле, чтобы увидеть, получаете ли вы то, что хотите.

person Eternal_Light    schedule 20.07.2011
comment
Мне удалось заставить все изображения отображаться сейчас. Спасибо всем, кто помог! Сейчас я просто имею дело с розоватым цветом фона изображения. - person tab2006; 21.07.2011

Создать панель, использующую GridLayout? Затем вы можете добавить на панель 12 JLabels, каждая из которых содержит ImageIcon. Таким образом, менеджер компоновки выполняет всю тяжелую работу по позиционированию и рисованию изображений.

person camickr    schedule 20.07.2011

Это можно сделать в java, ниже пример программы.

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class CombineImages {
    public static void main(String[] args) throws IOException {
        int imagesCount = 4;
        BufferedImage images[] = new BufferedImage[imagesCount];
        for(int j = 0; j < images.length; j++) {
            images[j] = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = images[j].createGraphics();
            g2d.drawRect(10, 10, 80, 80);
            g2d.dispose();
        }

        int heightTotal = 0;
        for(int j = 0; j < images.length; j++) {
            heightTotal += images[j].getHeight();
        }

        int heightCurr = 0;
        BufferedImage concatImage = new BufferedImage(100, heightTotal, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = concatImage.createGraphics();
        for(int j = 0; j < images.length; j++) {
            g2d.drawImage(images[j], 0, heightCurr, null);
            heightCurr += images[j].getHeight();
        }
        g2d.dispose();

        ImageIO.write(concatImage, "png", new File("/Users/kumarabhishek/Downloads/downloadedFiles/concat.png")); // export concat image
        ImageIO.write(images[0], "png", new File("/Users/kumarabhishek/Downloads/downloadedFiles/single.png"));

    }
}
person Kumar Abhishek    schedule 27.01.2020