【问题标题】:Java Combine multiple images into a single bigger image without overlappingJava 将多个图像组合成一个更大的图像而不重叠
【发布时间】:2011-07-20 20:01:19
【问题描述】:

我正在尝试使用 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");  
}
}

【问题讨论】:

  • 我注意到您在前三张图片中使用了 image 类型,但在其他所有图片中都使用了 bufferedimage 类型。这样做是出于特定原因吗?

标签: java bufferedreader javax.imageio


【解决方案1】:

我注意到的第一件事是,您在每次绘制图像后都在 Graphics2D 上调用 dispose()。这可能就是为什么您在较大的图像中只看到一个图像被绘制的原因。取出该调用并将其放在循环之后,您应该会开始看到更多图像。

附带说明,您可以大大简化 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);
}

【讨论】:

  • 我摆脱了 dispose(),但仍然只得到左上角的一个图像(我的布局中的第一个位置)。不过,那个 for 循环是很好的建议。我知道有一种方法可以简化它,只是不能完全围绕它说唱。谢谢!
  • 您在运行此方法时是否遇到任何异常?您可以使用ImageIO.write(page, "JPG", new File(outpath)); 尝试另一种保存图像的方式
【解决方案2】:

您在 for 循环内调用 dispose 方法,因此当程序完成循环内代码的第一次运行时,它会删除绘制对象。当第二次浏览循环时,程序找不到绘画对象,因此它既不能绘制下一张图像,也不能用白色填充房间。

在关闭 for 循环后立即尝试使用 dispose 方法。

您也可以尝试添加一些 println 方法来查看 imgs 项返回的长度。您通常应该检查您在循环中使用的变量内的数字,看看您是否得到了您想要的。

【讨论】:

  • 我已经设法让所有图像现在都显示出来。感谢所有帮助过的人!我现在只是将图像背景的颜色处理为粉红色。
【解决方案3】:

创建一个使用 GridLayout 的面板?然后,您可以将 12 个 JLabel 添加到面板中,每个标签都包含一个 ImageIcon。这样,布局管理器就可以完成定位和绘制图像的所有艰苦工作。

【讨论】:

    【解决方案4】:

    这可以在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"));
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 2022-06-25
      相关资源
      最近更新 更多