Select, Copy and Paste Images

前端 未结 2 915
南笙
南笙 2020-12-20 06:18

What I want my app to do:

1 - Select an area of Image and get the coordinates. This code below should do this:

import java.awt.*;
import java.awt.eve         


        
相关标签:
2条回答
  • 2020-12-20 06:55

    You need more listeners for button pressed and released.. some lines in the mouseMoved also better placed in mousePressed.
    You would want to update your captureRect when you release the mouse (in mouseReleased method).
    Then you just write it to the file. You may adjust other things according to your needs.

    And for clarity maybe it's better to add a save button into your UI.

    public class ScreenCaptureRectangle {
    
        Rectangle captureRect;
        Point start = new Point();
        SimpleDateFormat sdf;
    
        ScreenCaptureRectangle(final BufferedImage screen) {
            sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
            final BufferedImage screenCopy = new BufferedImage(
                    screen.getWidth(),
                    screen.getHeight(),
                    screen.getType());
            final JLabel screenLabel = new JLabel(new ImageIcon(screenCopy));
            JScrollPane screenScroll = new JScrollPane(screenLabel);
    
            screenScroll.setPreferredSize(new Dimension(
                    (int) (screen.getWidth() / 3),
                    (int) (screen.getHeight() / 3)));
    
            JPanel panel = new JPanel(new BorderLayout());
            panel.add(screenScroll, BorderLayout.CENTER);
            JButton btnSave = new JButton("SAVE");
            btnSave.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent ae) {
                    double w = captureRect.getWidth();
                    double h = captureRect.getHeight();
                    double x = captureRect.getX();
                    double y = captureRect.getY();
    
                    int W = (int) w;
                    int H = (int) h;
                    int X = (int) x;
                    int Y = (int) y;
    
                    BufferedImage selectImg = screen.getSubimage(X, Y, W, H);
                    try {
                        String fName = generateFileName();
                        if (fName != null) {
                            File f = new File(fName);
                            if (f.createNewFile()) {
                                ImageIO.write(selectImg, "jpg", f);
                            }
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(ScreenCaptureRectangle.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            panel.add(btnSave, BorderLayout.AFTER_LAST_LINE);
    
            final JLabel selectionLabel = new JLabel(
                    "Drag a rectangle in the screen shot!");
            panel.add(selectionLabel, BorderLayout.SOUTH);
    
            repaint(screen, screenCopy);
            screenLabel.repaint();
    
            screenLabel.addMouseMotionListener(new MouseMotionAdapter() {
    
                @Override
                public void mouseDragged(MouseEvent me) {
                    Point end = me.getPoint();
                    captureRect = new Rectangle(start,
                            new Dimension(end.x - start.x, end.y - start.y));
                    repaint(screen, screenCopy);
                    screenLabel.repaint();
                    selectionLabel.setText("Rectangle: " + captureRect);
                }
    
            });
    
            screenLabel.addMouseListener(new MouseAdapter() {
    
                @Override
                public void mousePressed(MouseEvent me) {
                    start = me.getPoint();
                    repaint(screen, screenCopy);
                    selectionLabel.setText("Start Point: " + start);
                    screenLabel.repaint();
                }
    
                @Override
                public void mouseReleased(MouseEvent me) {
                    int endX = me.getX();
                    int endY = me.getY();
                    if (endX > start.x && endY > start.y) {
                        captureRect = new Rectangle(start.x, start.y, endX-start.x, endY-start.y);
                        System.out.println("Rectangle of interest: " + captureRect);
                    }
                }
    
            });
    
            JOptionPane.showMessageDialog(null, panel);
        }
    
        private String generateFileName() {
            return new StringBuilder("screencrop_").append(sdf.format(new Date())).append(".jpg").toString();
        }
    
        public void repaint(BufferedImage orig, BufferedImage copy) {
            Graphics2D g = copy.createGraphics();
            g.drawImage(orig, 0, 0, null);
            if (captureRect != null) {
                g.setColor(Color.RED);
                g.draw(captureRect);
                g.setColor(new Color(255, 255, 255, 150));
                g.fill(captureRect);
            }
            g.dispose();
        }
    
        public static void main(String[] args) throws Exception {
            Robot robot = new Robot();
            final Dimension screenSize = Toolkit.getDefaultToolkit().
                    getScreenSize();
            final BufferedImage screen = robot.createScreenCapture(
                    new Rectangle(screenSize));
    
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new ScreenCaptureRectangle(screen);
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-12-20 06:57

    Start by taking a look at:

    • How to Write a Mouse Listener
    • How to Use Buttons, Check Boxes, and Radio Buttons
    • How to Write an Action Listeners
    • Performing Custom Painting
    • Writing/Saving an Image

    You need to take the concepts you have and rework them into a coherent workable solution. That is, provide functionality between the areas you need (selecting a region and saving the file) so that they work cleanly together...

    The following example takes a screenshot, allows you to select an area, click save and the file will be saved. The example checks to see how many files are already in the current directory and increments the count by 1 so you are not overwriting the existing files...

    Select my world

    import java.awt.AWTException;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.Robot;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileFilter;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class ScreenImage {
    
        public static void main(String[] args) {
            new ScreenImage();
        }
    
        public ScreenImage() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
                    try {
                        Robot robot = new Robot();
                        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                        final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
    
                        JFrame frame = new JFrame("Testing");
                        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        frame.add(new TestPane(screen));
                        frame.setSize(400, 400);
                        frame.setLocationRelativeTo(null);
                        frame.setVisible(true);
                    } catch (AWTException exp) {
                        exp.printStackTrace();
                    }
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private BufferedImage master;
    
            public TestPane(BufferedImage image) {
                this.master = image;
                setLayout(new BorderLayout());
                final ImagePane imagePane = new ImagePane(image);
                add(new JScrollPane(imagePane));
    
                JButton btnSave = new JButton("Save");
                add(btnSave, BorderLayout.SOUTH);
    
                btnSave.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            BufferedImage img = imagePane.getSubImage();
                            master = append(master, img);
                            File save = new File("Capture.png");
                            ImageIO.write(master, "png", save);
                            imagePane.clearSelection();
                            JOptionPane.showMessageDialog(TestPane.this, save.getName() + " was saved", "Saved", JOptionPane.INFORMATION_MESSAGE);
                        } catch (IOException ex) {
                            ex.printStackTrace();
                            JOptionPane.showMessageDialog(TestPane.this, "Failed to save capture", "Error", JOptionPane.ERROR_MESSAGE);
                        }
                    }
    
                    public BufferedImage append(BufferedImage master, BufferedImage sub) {
    
                        // Create a new image which can hold both background and the
                        // new image...
                        BufferedImage newImage = new BufferedImage(
                                        master.getWidth() + sub.getWidth(),
                                        Math.max(master.getHeight(), sub.getHeight()),
                                        BufferedImage.TYPE_INT_ARGB);
                        // Get new image's Graphics context
                        Graphics2D g2d = newImage.createGraphics();
                        // Draw the old background
                        g2d.drawImage(master, 0, 0, null);
                        // Position and paint the new sub image...
                        int y = (newImage.getHeight() - sub.getHeight()) / 2;
                        g2d.drawImage(sub, master.getWidth(), y, null);
                        g2d.dispose();
    
                        return newImage;
    
                    }
    
                });
    
            }
    
        }
    
        public class ImagePane extends JPanel {
    
            private BufferedImage background;
            private Rectangle selection;
    
            public ImagePane(BufferedImage img) {
                background = img;
                MouseAdapter ma = new MouseAdapter() {
    
                    private Point clickPoint;
    
                    @Override
                    public void mousePressed(MouseEvent e) {
                        clickPoint = e.getPoint();
                    }
    
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        Point dragPoint = e.getPoint();
    
                        int x = Math.min(clickPoint.x, dragPoint.x);
                        int y = Math.min(clickPoint.y, dragPoint.y);
                        int width = Math.abs(clickPoint.x - dragPoint.x);
                        int height = Math.abs(clickPoint.y - dragPoint.y);
    
                        selection = new Rectangle(x, y, width, height);
                        repaint();
    
                    }
    
                };
    
                addMouseListener(ma);
                addMouseMotionListener(ma);
            }
    
            public void clearSelection() {
                selection = null;
                repaint();
            }
    
            public BufferedImage getSubImage() {
    
                BufferedImage img = null;
                if (selection != null) {
    
                    img = background.getSubimage(selection.x, selection.y, selection.width, selection.height);
    
                }
                return img;
    
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(background.getWidth(), background.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - background.getWidth()) / 2;
                int y = (getHeight() - background.getHeight()) / 2;
                g2d.drawImage(background, x, y, this);
                if (selection != null) {
                    Color stroke = UIManager.getColor("List.selectionBackground");
                    Color fill = new Color(stroke.getRed(), stroke.getGreen(), stroke.getBlue(), 128);
                    g2d.setColor(fill);
                    g2d.fill(selection);
                    g2d.setColor(stroke);
                    g2d.draw(selection);
                }
                g2d.dispose();
            }
    
        }
    
    }
    

    So apart from rendering the selection the hardest part would be generating the resulting image...

    Basically, this done by creating a new BufferedImage and painting the old image and the new, sub, image together.

    public BufferedImage append(BufferedImage master, BufferedImage sub) {
    
        // Create a new image which can hold both background and the
        // new image...
        BufferedImage newImage = new BufferedImage(
                        master.getWidth() + sub.getWidth(),
                        Math.max(master.getHeight(), sub.getHeight()),
                        BufferedImage.TYPE_INT_ARGB);
        // Get new image's Graphics context
        Graphics2D g2d = newImage.createGraphics();
        // Draw the old background
        g2d.drawImage(master, 0, 0, null);
        // Position and paint the new sub image...
        int y = (newImage.getHeight() - sub.getHeight()) / 2;
        g2d.drawImage(sub, master.getWidth(), y, null);
        g2d.dispose();
    
        return newImage;
    
    }
    

    The example replaces the previous (master) image with the one created here, so it will constantly be appending new images to the end of it...

    0 讨论(0)
提交回复
热议问题