选择,复制和粘贴图像 [英] Select, Copy and Paste Images

查看:157
本文介绍了选择,复制和粘贴图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的应用做什么:

What I want my app to do:

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

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

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方法上使用它。

2 - get the coordinates and use it on getSubimage method.

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 - 此代码创建一个新的图像文件并复制所选的图像。

3 - this code create a new image file and copy the imageselected.

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的想法是:

- 选择图像的一个区域。$
- 复制该图像并粘贴到其他文件中。 (当我按下任何按钮时)

- 程序将继续运行,直到我按下另一个按钮。

- 我复制程序的每个图像都会粘贴到最后一个按钮旁边。

The idea of app is:
- Select an area of the image.
- Copy that image and paste in other file. ( when I pressed any button )
- The program will continue run until I press another button.
- Every image that I copy the program will paste it beside the last one.

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

I think I am near to the solution. Can any one help me to "connect the parts" ?

推荐答案

首先来看看:

  • 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

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

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...

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

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...

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...

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

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...

这篇关于选择,复制和粘贴图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆