[英]Split image into clickable regions
Is there any way to split an image to region (right now it's JLabel but I can change it if necessary)? 有没有办法将图像分割成区域(现在它是JLabel但我可以在必要时更改它)?
I use swing in my program and I have an image (square for this example) with some triangles, stars and trapezoids inside it (it can be JPG, PNG, etc). 我在我的程序中使用swing并且我有一个图像(这个例子是正方形),里面有一些三角形,星形和梯形(它可以是JPG,PNG等)。
The idea is that the user will click inside one of those shapes and then I will put another small icon on top of the area the user clicked. 想法是用户将在其中一个形状中单击,然后我将在用户单击的区域顶部放置另一个小图标。 The user can click on multiple areas but at the end of the day, I need to know which shapes were clicked. 用户可以点击多个区域,但在一天结束时,我需要知道点击了哪些形状。
Seems possible anyone? 似乎有可能有人吗?
Have a look at what I have made: 看看我做了什么:
This is the image I used for testing: 这是我用于测试的图像:
After image has been split: 图像分割后:
And here is the source: 以下是来源:
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;
}
}
The only flaw is I haven't checked if the image is larger then the screen which could cause problems, that would be resolved by a simple image resize using getScaledInstance(int x,int y, int width, in height)
on the image and the separating it into chunks. 唯一的缺陷是我没有检查图像是否大于可能导致问题的屏幕,这可以通过使用图像上的getScaledInstance(int x,int y, int width, in height)
进行简单的图像调整来解决。把它分成块。
Sorry I missed the part if the question in Shapes, have a look at draw(Shape s)
method of Graphics2D
/ Graphics
. 抱歉,如果Shapes中有问题,我会错过这个部分,看看Graphics2D
/ Graphics
draw(Shape s)
方法。
I read this: 我看了这个:
Any Shape object can be used as a clipping path that restricts the portion of the drawing area that will be rendered. 任何Shape对象都可以用作限制将要渲染的绘图区域部分的剪切路径。 The clipping path is part of the
Graphics2D
context; 剪切路径是Graphics2D
上下文的一部分; to set the clip attribute, you callGraphics2D.setClip
and pass in the Shape that defines the clipping path you want to use. 要设置剪辑属性,请调用Graphics2D.setClip
并传入定义要使用的剪切路径的Shape。
See here for clipping an u]image to a shape: Clipping the Drawing Region 请参见此处将u]图像剪切为形状: 剪切绘图区域
References: 参考文献:
You can use the getSubImage()
method of BufferedImage
, illustrated here and here . 您可以使用BufferedImage
的getSubImage()
方法, 此处和此处说明。 The example also uses JLabel
, but you can add the Icon
to a JButton
that can be clicked. 该示例还使用了JLabel
,但您可以将Icon
添加到可以单击的JButton
中。 There are several ways for a button to remember details about it's icon: 按钮有几种方法可以记住有关它的图标的详细信息:
JButton
and add a suitable field. 子类JButton
并添加一个合适的字段。 JComponent
. 将客户端属性添加到父JComponent
。 name
property of the parent Component
. 使用父Component
的name
属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.