Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 选择、复制和粘贴图像_Java_Image_Copy Paste - Fatal编程技术网

Java 选择、复制和粘贴图像

Java 选择、复制和粘贴图像,java,image,copy-paste,Java,Image,Copy Paste,我希望我的应用程序执行的操作: 1-选择图像区域并获取坐标。下面的代码应执行以下操作: import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; public class ScreenCaptureRectangle { Rectangle captureRect; ScreenCaptureRectangle(final BufferedImage screen)

我希望我的应用程序执行的操作:

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);
app的理念是:
-选择图像的一个区域。
-复制该图像并粘贴到其他文件中。(当我按下任何按钮时)
-程序将继续运行,直到我按下另一个按钮。
-我复制程序的每个图像都将粘贴到最后一个图像旁边。


我想我已经接近解决办法了。有人能帮我“连接部件”吗?

你需要更多的监听器来按下和释放按钮。。
mouseMoved
中的某些行也最好放在
mousempressed

当您释放鼠标时(在
mousererelease
方法中),您可能希望更新您的
captureRect

然后你就把它写到文件里。你可以根据需要调整其他东西

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

首先看一下:

您需要将现有的概念重新整理成一个连贯可行的解决方案。也就是说,在您需要的区域之间提供功能(选择区域并保存文件),以便它们可以干净地协同工作

下面的示例获取一个屏幕截图,允许您选择一个区域,单击“保存”,文件将被保存。该示例检查当前目录中已有多少文件,并将计数增加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;

}

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

“当我按下任何底部时”-你是说“按钮”?“我复制程序的每个图像都将粘贴到最后一个图像旁边”-我想这意味着在屏幕上,还是说文件应该按顺序命名?是的,你是对的。它在同一屏幕上显示。我只想要一个图像文件。非常感谢你。我试图理解你做了什么,但这是完美的再次感谢你。我试着研究你提到的主题,但都是英文的,更难理解。对于biggeners,您是否指出了书[Java:How to program-Deitel]?(有一个葡萄牙语版本)我将尝试尽快更新示例,将图像复制回屏幕。你没有读的那本书对你没有帮助。没有一本书能告诉你一切。但是,请尝试获得一个合理的最新版本,因为API最近经历了一些更改;)哈哈,你说得对。我将学习更多的编程。只是为了澄清这个想法:程序应该将图像的每个选定区域粘贴到另一个文件图像中。一个接一个。其思想是像处理字符串一样连接图像。(:那么你不想把新剪辑也添加到屏幕/用户界面中?只是添加到文件中?@MadProgrammer可能会编写你想要的所有功能,但是,依我看,如果你能先试试的话会更好,Marco。根据目前的答案,正如你所说,你接近最终的解决方案了。谢谢你,Yohanes。真的很好。很抱歉我的英语不好。什么我想说的是:将所有选定区域放在同一个文件图像上。一个挨着另一个。我的建议是:制作一个
矩形
列表,并添加一个按钮
捕获
。每次单击
捕获
,你都应该在
列表中添加一个新的
矩形点击“保存”
,你应该迭代这些矩形并获得总大小(这取决于你想如何组合它们),然后像你想的那样在一个
buffereImage
中绘制每个子图像。当你尝试这个方法时遇到更多问题,请稍后再问(我认为在新的帖子中会更好).祝你好运!嗨,尤汉斯。我照你说的做了,但列表的长度有限。所以我找到了以下代码:[code]ArrayList al=new ArrayList();al.add(new Rectangle(x,y,w,h));[/code],但它不起作用。你能帮我吗?我是在facebook上找到你的。我们可以在那里谈谈吗?还是通过电子邮件?这样更容易些