0

I write an application with the ability for the user to cut images. Currently, the code below cut the image a little bit above the drawn rectangle(whose purpose is to show with which coordinates the user wants to cut the image, actually.)

public class ScreenCaptureRectangle extends JFrame implements MouseListener, MouseMotionListener {

int drag_status = 0, c1, c2, c3, c4;

public void cut() {
    ImagePanel im = new ImagePanel(PicChanges.getNewImage());
    JScrollPane scrollPane = new JScrollPane(im);
    add(scrollPane);
    setSize(500, 400);
    setVisible(true);
    im.addMouseListener(this);
    im.addMouseMotionListener(this);
}

public void draggedScreen() throws Exception {
    int w = c1 - c3;
    int h = c2 - c4;
    w = w * -1;
    h = h * -1;
    Robot robot = new Robot();
    BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2, w, h));
    File save_path = new File("screen1.jpg");
    ImageIO.write(img, "JPG", save_path);
    System.out.println("Cropped image saved successfully.");
}

@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

@Override
public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
    repaint();
    c1 = arg0.getX();
    c2 = arg0.getY();
}

@Override
public void mouseReleased(MouseEvent arg0) {
    repaint();
    if (drag_status == 1) {
        c3 = arg0.getX();
        c4 = arg0.getY();
        try {
            repaint();
            draggedScreen();
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        System.out.println("Issue is under construction");
    }
}

@Override
public void mouseDragged(MouseEvent arg0) {
    repaint();
    drag_status = 1;
    c3 = arg0.getX();
    c4 = arg0.getY();
}

@Override
public void mouseMoved(MouseEvent arg0) {
}

public void paint(Graphics g) {
    super.paint(g);
    int w = c1 - c3;
    int h = c2 - c4;
    w = w * -1;
    h = h * -1;
    if (w < 0)
        w = w * -1;
    g.setColor(Color.RED);
    g.drawRect(c1, c2, w, h);
}

public class ImagePanel extends JPanel {

private BufferedImage imageToCut;


public ImagePanel(BufferedImage img) {
    this.imageToCut = img;
    Dimension size = new Dimension(imageToCut.getWidth(null), imageToCut.getHeight(null));
    setPreferredSize(size);
    setMaximumSize(size);
    setMinimumSize(size);
    setSize(size);
}

@Override
protected void paintComponent(Graphics g) {
    g.drawImage(imageToCut, 0, 0, null);
}
}

As of for now when the user crops image like this:

enter image description here

He gets this:

enter image description here

My target is to get the following result:

enter image description here

I use mouse listeners so to get the coordinates of the drawn rectangle and then using these coordinates cut the image. Now the image is cut with incorrect height(as I see it). I would appreciate it if anyone could tell me what can be wrong in the code? Thanks!

Ilona
  • 357
  • 3
  • 10
  • 1
    1) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). E.G. like in [this answer](https://stackoverflow.com/a/11007422/418556) (which seems to be the basis for this question!). 2) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. Please [edit] the question to add 4 space chars ahead of the closing `}` at the end of the code. – Andrew Thompson Apr 22 '19 at 08:14
  • 1
    If you're going to use `Robot`, you need to change the coordinates reported by `MouseEvent` to be screen coordinates, they are currently reported as component coordinates relative to the component the `MouseListener` is registered to – MadProgrammer Apr 22 '19 at 08:52
  • 1
    Also, because the components are relative to the `ImagePanel`, the rectangle you're painting on your frame will be misrepresented – MadProgrammer Apr 22 '19 at 08:57
  • 1
    You will want to look at [`MouseEvent#getLocationOnScreen`](https://docs.oracle.com/javase/10/docs/api/java/awt/event/MouseEvent.html#getLocationOnScreen()) – MadProgrammer Apr 22 '19 at 08:59
  • 1
    The robot cuts with respect to the screen - the coordinates of the mouse point are with respect to the window of the program - so you need to play with that - start with the start of your program window and add that to the beginning of your computer screen - then if you have a JPanel inside a Frame that will also change the relative coordinates - so you need to play - put rectangles in each case to see where the points are – gpasch Apr 22 '19 at 15:29
  • Thank you, @MadProgrammer, you were right about the coordinates reported by MouseEvent - I changed them. Also,@gpasch thanks for your recommendations, as a result, I don't open a separate window for the photo to cut, I add MouseListeners to JFrame and now cut works as expected, even better!) – Ilona Apr 24 '19 at 07:23

1 Answers1

1

Thanks to the recommendations I received, now I don't open a separate frame for a photo to cut after a user clicks on the Cut button, I just add MouseListeners to JFrame, which is more convenient and user-friendly. The photo is cut correctly, according to the coordinates from the MouseListeners:

public class ImageScreenShot extends JFrame implements MouseListener, MouseMotionListener {

int drag_status = 0, c1, c2, c3, c4;

public int getC1() {
    return c1;
}

public int getC2() {
    return c2;
}

public int getC3() {
    return c3;
}

public int getC4() {
    return c4;
}

public void cut() {
    GraphicalUserInterface.getFrame().addMouseMotionListener(this);
    GraphicalUserInterface.getFrame().addMouseListener(this);
}

public void draggedScreen() throws Exception {
    int w = c1 - c3;
    int h = c2 - c4;
    w = w * -1;
    h = h * -1;
    Robot robot = new Robot();
    BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2, w, h));
    File save_path = new File("screen1.jpg");
    ImageIO.write(img, "JPG", save_path);
    GraphicalUserInterface.getLabelIcon().setIcon(new ImageIcon(new ImageIcon(img).getImage().getScaledInstance(img.getWidth(), img.getHeight(), Image.SCALE_SMOOTH)));
    JOptionPane.showConfirmDialog(null, "Would you like to save your cropped Pic?");
    if (JOptionPane.YES_OPTION == 0) {
    /**Need to implement some code*/
    } else {
    /**Need to implement some code*/

    }
    System.out.println("Cropped image saved successfully.");
}

@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

@Override
public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
    c1 = arg0.getXOnScreen();
    c2 = arg0.getYOnScreen();
}

@Override
public void mouseReleased(MouseEvent arg0) {
    if (drag_status == 1) {
        c3 = arg0.getXOnScreen();
        c4 = arg0.getYOnScreen();
        try {
            draggedScreen();
        } catch (Exception e) {
            e.printStackTrace();
        }
    } else {
        System.out.println("Issue is under construction");
    }
}

@Override
public void mouseDragged(MouseEvent arg0) {
    drag_status = 1;
    c3 = arg0.getXOnScreen();
    c4 = arg0.getYOnScreen();
}

@Override
public void mouseMoved(MouseEvent arg0) {
}
Ilona
  • 357
  • 3
  • 10