在Java中并排显示图片

时间:2019-01-28 13:49:42

标签: java swing javax.imageio

是否可以使用BufferedImage和Graphics2D并排显示两个图片?还是应该使用其他方法?

在下面的代码中,我能够显示两个图像,但是图片1与图片2重叠。

package zdjecie;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ObrazPanel extends JPanel {

    private BufferedImage image;
    private BufferedImage image2;

    public ObrazPanel() {
        super();

    File imageFile = new File("C:\\Users\\KostrzewskiT\\eclipse-workspace\\zdjecie\\src\\zdjecie\\java.jpg");
    File imageFile2 = new File("C:\\Users\\KostrzewskiT\\eclipse-workspace\\zdjecie\\src\\zdjecie\\java2.jpg"); 

        try {
            image = ImageIO.read(imageFile);
            image2 = ImageIO.read(imageFile2);
        } catch (IOException e) {
            System.err.println("Blad odczytu obrazka");
            e.printStackTrace();
        }


        Dimension dimension = new Dimension(image.getWidth(), image.getHeight());
        setPreferredSize(dimension);
        Dimension dimension2 = new Dimension(image2.getWidth(), image2.getHeight());
        setPreferredSize(dimension2);
    }


    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image, 0, 0, this);
        g2d.drawImage(image2, 200, 200, this);
    }
}

4 个答案:

答案 0 :(得分:3)

您两次致电setPreferredSize,这导致第一次致电基本上无所作为。这意味着您始终拥有preferredSize等于第二张图像的尺寸。您应该要做的是假设两者的高度相同,将尺寸设置为new Dimension(image.getWidth() + image2.getWidth(), image2.getHeight())。如果不是这种情况,请将height设置为两个图像的最大值。

第二步,您需要将第二张图片与第一张图片的位置恰好偏移第一张图片的宽度:

g2d.drawImage(image, 0, 0, this);
g2d.drawImage(image2, image.getWidth(), 0, this);

答案 1 :(得分:1)

我在您的代码中发现了一些错误,但是我没有得到您想要做什么...

1]在那儿,您实际上没有使用第一个设置

    Dimension dimension = new Dimension(image.getWidth(), image.getHeight());
    setPreferredSize(dimension); //not used
    Dimension dimension2 = new Dimension(image2.getWidth(), image2.getHeight());
    setPreferredSize(dimension2); //because overridden by this

这意味着面板的尺寸与image2相同,您应按以下步骤进行设置:

  • 高度作为两个图像的高度的最大值
  • 宽度至少作为两张图片的宽度的总和(如果您要尝试在同一面板上绘制它们的话)

2]什么是imageimage2数据类型?在上面的代码块中,您拥有File但具有不同的命名变量,File课程类别没有width或height参数

我假设它在Graphics.drawImage中应有的使用Image,然后:

您需要设置首选尺寸,正如我提到的:

  • 从图像高度到最大值的高度
  • 宽度至少作为每个宽度的汇总值

标注尺寸:

Dimension panelDim = new Dimension(image.getWidth() + image2.getWidth(),Math.max(image.getHeight(),image2.getHeight()));
setPreferredSize(panelDim)

然后,您可以以原始大小绘制图像 -适当的坐标在左上角具有0; 0,在右下角是this.getWidth();。 this.getHeight() -检查例如。 this explanation -您需要在左下角开始绘制,然后移动到正确的位置,将“ X”作为第一张图片的宽度增加

@Override
public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
        /* public abstract boolean drawImage(Image img,
        int x,
        int y,
        Color bgcolor,
        ImageObserver observer)
        */
    //start to paint at [0;0]
    g2d.drawImage(image, 0, 0, this); 
    //start to paint just on the right side of first image (offset equals to width of first picture)- next pixel on the same line, on the bottom of the screen 
    g2d.drawImage(image2,image2.getWidth()+1, 0, this);
}

我没有机会进行测试,但是应该是这样。 重要的事情是

  • 您需要具有合适的尺寸以适合两个图像
  • 屏幕坐标始于屏幕[0; 0]的左上角

答案 2 :(得分:1)

数学逻辑不正确。有关计算所需宽度的正确方法,请参见getPreferredSize()方法,以及对paintComponent(Graphics)方法的更改以使其并排放置。

另一种方法(未在此答案中进行检查)是将每张图像放入JLabel中,然后将标签添加到具有适当布局的面板中。

这是更改的结果:

enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.net.*;
import javax.imageio.ImageIO;

public class ObrazPanel extends JPanel {

    private BufferedImage image;
    private BufferedImage image2;

    public ObrazPanel() throws MalformedURLException {
        super();

        URL imageFile = new URL("https://i.stack.imgur.com/7bI1Y.jpg");
        URL imageFile2 = new URL("https://i.stack.imgur.com/aH5zB.jpg");

        try {
            image = ImageIO.read(imageFile);
            image2 = ImageIO.read(imageFile2);
        } catch (Exception e) {
            System.err.println("Blad odczytu obrazka");
            e.printStackTrace();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        int w = image.getWidth() + image2.getWidth();
        int h1 = image.getHeight();
        int h2 = image2.getHeight();
        int h = h1>h2 ? h1 : h2;
        return new Dimension(w,h);
    }

    @Override
    public void paintComponent(Graphics g) {
        // always best to start with this.. 
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image, 0, 0, this);
        g2d.drawImage(image2, image.getWidth(), 0, this);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                ObrazPanel o;
                try {
                    o = new ObrazPanel();
                    JFrame f = new JFrame(o.getClass().getSimpleName());
                    f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    f.setLocationByPlatform(true);

                    f.setContentPane(o);
                    f.pack();
                    f.setMinimumSize(f.getSize());

                    f.setVisible(true);
                } catch (MalformedURLException ex) {
                    ex.printStackTrace();
                }
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

答案 3 :(得分:0)

只要有什么变化,我都会加入图像并将它们绘制到另一个缓冲图像上。然后,只要需要重新绘制面板,我就可以重新绘制组合图像。

Application

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

public class SideBySideImagePanel extends JPanel {
    private static final long serialVersionUID = 5868633578732134172L;
    private BufferedImage left;
    private BufferedImage right;
    private BufferedImage join;

    public SideBySideImagePanel() {
        ClassLoader loader = this.getClass().getClassLoader();
        BufferedImage left = null, right = null;

        try {
            left = ImageIO.read(loader.getResourceAsStream("resources/Android.png"));
            right = ImageIO.read(loader.getResourceAsStream("resources/Java.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        this.setLeft(left);
        this.setRight(right);
    }

    public BufferedImage getLeft() {
        return left;
    }

    public void setLeft(BufferedImage left) {
        this.left = left;
    }

    public BufferedImage getRight() {
        return right;
    }

    public void setRight(BufferedImage right) {
        this.right = right;
    }

    @Override
    public void invalidate() {
        super.invalidate();
        join = combineImages(left, right);
        setPreferredSize(new Dimension(join.getWidth(), join.getHeight()));
    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(join, 0, 0, null);
    }

    private BufferedImage combineImages(BufferedImage left, BufferedImage right) {
        int width = left.getWidth() + right.getWidth();
        int height = Math.max(left.getHeight(), right.getHeight());
        BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 
        Graphics g = combined.getGraphics();

        g.drawImage(left, 0, 0, null);
        g.drawImage(right, left.getWidth(), 0, null);

        return combined;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Image Joiner");
                SideBySideImagePanel panel = new SideBySideImagePanel();

                frame.getContentPane().add(panel);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}