将图像拆分为可点击区域

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

似乎有人可能吗?

看看我做了什么:

这是我用于测试的图像:

原始图像

图像分割后:

图像分割后

以下是来源:

 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; } } 

唯一的缺陷是我没有检查图像是否大于可能导致问题的屏幕,这可以通过使用图像上的getScaledInstance(int x,int y, int width, in height)的简单图像大小来解决。把它分成块。

更新

对不起,如果Shapes中的问题,我错过了部分,看看Graphics2D / Graphics draw(Shape s)方法。

我看了这个:

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

请参见此处将u]图像剪切为形状: 剪切绘图区域

参考文献:

  • 如何将图像分割成块 - Java ImageIO

您可以使用BufferedImagegetSubImage()方法, 此处和此处说明。 该示例还使用了JLabel ,但您可以将Icon添加到可以单击的JButton中。 按钮有几种方法可以记住有关它的图标的详细信息:

  • 子类JButton并添加一个合适的字段。
  • 将客户端属性添加到父JComponent
  • 使用父Componentname属性。