Divide image into interactive areas

Is there a way to divide the image into an area (now it's JLabel, but I can change it if necessary)?
I use swing in my program, and I have an image (a square for this example) with some triangles, stars and trapezoids inside it (it can be JPG, PNG, etc.). The idea is that the user clicks inside one of these shapes, and then put another small icon on top of the area that the user clicked on. A user can click on several areas, but at the end of the day I need to know which forms were clicked.

Does anyone seem possible?

+4
source share
2 answers

See what I did:

This is the image I used for testing:

Original image

after splitting the image:

After image splitting

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 drawback: I did not check if the image is larger than the screen, which can cause problems that will be resolved by simply resizing the image using getScaledInstance(int x,int y, int width, in height) on the image and dividing it into pieces.

EDIT / UPDATE:

Sorry, I missed the part if the question is in the figure, look at the draw(Shape s) Graphics2D / Graphics method.

I read this:

Any Shape object can be used as a clipping path that limits the portion of the drawing area to be displayed. Clipping path is part of the Graphics2D context; to set the attribute of the clip, you call Graphics2D.setClip and submit in the form that defines the clipping path you want to use.

see here to crop the image u] in the form: Cropping a drawing area

Literature:

+8
source

You can use the getSubImage() method of the BufferedImage , illustrated here and here . The example also uses JLabel , but you can add an Icon to JButton , which you can click. There are several ways for a button to remember information about this icon:

  • Subclass JButton and add a suitable field.
  • Add the client property to the parent JComponent .
  • Use the name property of the parent Component .
+4
source

Source: https://habr.com/ru/post/1434127/


All Articles