Java 将图像分割为可单击的区域

Java 将图像分割为可单击的区域,java,image,swing,jlabel,java-2d,Java,Image,Swing,Jlabel,Java 2d,有没有办法将图像分割为区域(现在是JLabel,但必要时我可以更改)? 我在程序中使用swing,我有一个图像(本例中为正方形),其中包含一些三角形、星形和梯形(可以是JPG、PNG等)。 这个想法是,用户将单击其中一个形状,然后我将在用户单击的区域顶部放置另一个小图标。用户可以单击多个区域,但在一天结束时,我需要知道单击了哪些形状 似乎任何人都可能?您可以使用buffereImage的getSubImage()方法,如图所示。该示例还使用了JLabel,但您可以将图标添加到可以单击的JButt

有没有办法将图像分割为区域(现在是JLabel,但必要时我可以更改)?
我在程序中使用swing,我有一个图像(本例中为正方形),其中包含一些三角形、星形和梯形(可以是JPG、PNG等)。
这个想法是,用户将单击其中一个形状,然后我将在用户单击的区域顶部放置另一个小图标。用户可以单击多个区域,但在一天结束时,我需要知道单击了哪些形状


似乎任何人都可能?

您可以使用
buffereImage
getSubImage()
方法,如图所示。该示例还使用了
JLabel
,但您可以将
图标添加到可以单击的
JButton
。有几种方法可以让按钮记住其图标的详细信息:

  • 子类
    JButton
    ,并添加合适的字段
  • 将客户端属性添加到父组件
    JComponent
  • 使用父
    组件的
    名称
    属性

看看我做了什么:

这是我用于测试的图像:

分割图像后:

以下是资料来源:

import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class Test {

    private JFrame frame;
    private JLabel[] labels;
    private static String imagePath = "c:/test.jpg";
    private final int rows = 3; //You should decide the values for rows and cols variables
    private final int cols = 3;
    private final int chunks = rows * cols;
    private final int SPACING = 10;//spacing between split images

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Test().createAndShowUI();
            }
        });
    }

    private void createAndShowUI() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initComponents();
        frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }

    private void initComponents() {

        BufferedImage[] imgs = getImages();

        //set contentpane layout for grid
        frame.getContentPane().setLayout(new GridLayout(rows, cols, SPACING, SPACING));

        labels = new JLabel[imgs.length];

        //create JLabels with split images and add to frame contentPane
        for (int i = 0; i < imgs.length; i++) {
            labels[i] = new JLabel(new ImageIcon(Toolkit.getDefaultToolkit().createImage(imgs[i].getSource())));
            frame.getContentPane().add(labels[i]);
        }
    }

    private BufferedImage[] getImages() {
        File file = new File(imagePath); // I have bear.jpg in my working directory
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        BufferedImage image = null;
        try {
            image = ImageIO.read(fis); //reading the image file
        } catch (IOException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
        int chunkWidth = image.getWidth() / cols; // determines the chunk width and height
        int chunkHeight = image.getHeight() / rows;
        int count = 0;
        BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks
        for (int x = 0; x < rows; x++) {
            for (int y = 0; y < cols; y++) {
                //Initialize the image array with image chunks
                imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());

                // draws the image chunk
                Graphics2D gr = imgs[count++].createGraphics();
                gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);
                gr.dispose();
            }
        }
        return imgs;
    }
}
导入java.awt.Graphics2D;
导入java.awt.GridLayout;
导入java.awt.Toolkit;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileNotFoundException;
导入java.io.IOException;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.imageio.imageio;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingUtilities;
公开课考试{
私有JFrame;
专用JLabel[]标签;
私有静态字符串imagePath=“c:/test.jpg”;
private final int rows=3;//您应该决定rows和cols变量的值
私人最终整数=3;
私有最终整数块=行*列;
私有最终整数间距=10;//分割图像之间的间距
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新建测试().createAndShowUI();
}
});
}
私有void createAndShowUI(){
框架=新的JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
初始化组件();
frame.setresizeable(false);
frame.pack();
frame.setVisible(true);
}
私有组件(){
BuffereImage[]imgs=getImages();
//设置网格的contentpane布局
frame.getContentPane().setLayout(新的GridLayout(行、列、间距、间距));
标签=新的JLabel[imgs.length];
//使用拆分图像创建JLabel并添加到框架内容窗格
对于(int i=0;i
唯一的缺陷是我没有检查图像是否比屏幕大,这可能会导致问题,这可以通过在图像上使用
getScaledInstance(int x,int y,int width,in height)
调整图像大小并将其分块来解决

更新 很抱歉,如果问题是形状,请看一下
图形2d
/
图形的方法

我读到:

任何形状对象都可以用作限制形状的剪裁路径 将被渲染的绘图区域的一部分。剪切路径 是
图形2D
上下文的一部分;要设置剪辑属性,请调用
Graphics2D.setClip
并传入定义剪裁的形状 要使用的路径

有关将u]图像剪裁为形状的信息,请参见此处:

参考文献:


您是否已经知道如何将大图像分成精灵(每个单独的形状)?如果是这样的话,这应该相当容易。只需将子图像用作切换按钮的
GridLayout
图标即可。所以答案是“是的,这似乎是可能的”。我应该在哪里更改它,这样这些图像之间就没有差距了?对不起,没有问题