将图像拆分为可点击区域
有没有办法将图像分割成区域(现在它是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
您可以使用BufferedImage
的getSubImage()
方法, 此处和此处说明。 该示例还使用了JLabel
,但您可以将Icon
添加到可以单击的JButton
中。 按钮有几种方法可以记住有关它的图标的详细信息:
- 子类
JButton
并添加一个合适的字段。 - 将客户端属性添加到父
JComponent
。 - 使用父
Component
的name
属性。