选择,复制和粘贴图像

我想要我的应用程序做什么:

1 – 选择图像区域并获取坐标。 下面的代码应该这样做:

import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; public class ScreenCaptureRectangle { Rectangle captureRect; ScreenCaptureRectangle(final BufferedImage screen) { 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); 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() { Point start = new Point(); @Override public void mouseMoved(MouseEvent me) { start = me.getPoint(); repaint(screen, screenCopy); selectionLabel.setText("Start Point: " + start); screenLabel.repaint(); } @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); } }); JOptionPane.showMessageDialog(null, panel); System.out.println("Rectangle of interest: " + captureRect); } 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); } }); } } 

2 – 获取坐标并在getSubimage方法上使用它。

 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); 

3 – 此代码创建一个新的图像文件并复制所选的图像。

 BufferedImage img = new BufferedImage ( 5000, 5000, BufferedImage.TYPE_INT_RGB ); img.createGraphics().drawImage(selectImg, 0, 0, null); File final_image = new File("C:/Final.jpg"); ImageIO.write(img, "jpeg", final_image); 

应用程序的想法是:
– 选择图像的一个区域。
– 复制该图像并粘贴到其他文件中。 (当我按下任何按钮时)
– 程序将继续运行,直到我按下另一个按钮。
– 我复制程序的每个图像都会将其粘贴到最后一个图像旁边。

我想我接近解决方案。 任何人都可以帮我“连接部件”吗?

首先来看看:

  • 如何编写鼠标侦听器
  • 如何使用按钮,复选框和单选按钮
  • 如何编写动作监听器
  • 执行自定义绘画
  • 写/保存图像

您需要掌握所拥有的概念,并将其重新编写为一个连贯的可行解决方案。 也就是说,在您需要的区域之间提供function(选择区域并保存文件),以便它们一起干净地工作……

以下示例采用屏幕截图,允许您选择区域,单击“保存”,文件将被保存。 该示例检查当前目录中已有多少文件并将计数递增1,因此您不会覆盖现有文件…

选择我的世界

 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(); } } } 

因此除了渲染选择之外,最难的部分是生成结果图像……

基本上,这是通过创建一个新的BufferedImage并将旧图像和新的子图像一起绘制来完成的。

 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; } 

该示例将先前(主)图像替换为此处创建的图像,因此它将不断地将新图像附加到其末尾…

按下并释放按钮需要更多的监听器.. mouseMoved某些行也更好地放置在mousePressed
您希望在释放鼠标时更新captureRect (在mouseReleased方法中)。
然后你就把它写到文件中。 您可以根据自己的需要调整其他内容。

为清楚起见,最好在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); } }); } }