我正在制作截图程序,所以当你按下屏幕截图按钮时,会弹出一个JMessageDial并提示你你的图像,它会告诉你拖动鼠标并在你要拍摄的区域周围做一个方框截图。当用户点击“OK”时,我似乎无法找到如何在框内获取图像。
所以我需要帮助的是让用户用鼠标“绘制”矩形内部的图像,并将其存储在变量中。
以下是具体代码:
public void selectArea(final BufferedImage screen) throws Exception {
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()/2), (int)(screen.getHeight()/2)));
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
final JLabel selectionLabel = new JLabel("Draw a rectangle");
panel.add(selectionLabel, BorderLayout.SOUTH);
repaint(screen, screenCopy);
screenLabel.repaint();
screenLabel.addMouseMotionListener(new MouseMotionAdapter() {
@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) {
end = me.getPoint();
captureRect = new Rectangle(start, new Dimension(end.x-start.x, end.y-start.y));
try {
paintFinalImage(new BufferedImage((int)screenCopy.getGraphics().getClipBounds(captureRect).getWidth()+1,
(int)screenCopy.getGraphics().getClipBounds(captureRect).getHeight()+1, screen.getType()));
} catch (Exception e) {
e.printStackTrace();
}
repaint(screen, screenCopy);
screenLabel.repaint();
selectionLabel.setText("Rectangle: " + captureRect);
}
});
JOptionPane.showMessageDialog(null, panel, "Select your image", JOptionPane.OK_OPTION, new ImageIcon(""));
uploadImage(screenShot);
System.out.println("Final rectangle: " + screenCopy.getGraphics().getClipBounds(captureRect));
}
如果你需要,这是完整的课程:
package com.screencapture;
import java.awt.*;
public class Main implements ActionListener, ItemListener, KeyListener, NativeKeyListener {
private final Image icon = Toolkit.getDefaultToolkit().getImage("./data/icon.gif");
private final TrayIcon trayIcon = new TrayIcon(icon, "Screen Snapper");
private JFrame frame;
private Rectangle captureRect;
private JComboBox<String> imageType;
private boolean hideWhenMinimized = false;
private final String API_KEY = "b84e430b4a65d16a6955358141f21a61";
private static Robot robot;
private BufferedImage screenShot;
private Point end;
private Point start;
public static void main(String[] args) throws Exception {
robot = new Robot();
new Main().start();
}
public void start() throws Exception {
GlobalScreen.getInstance().registerNativeHook();
GlobalScreen.getInstance().addNativeKeyListener(this);
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
frame = new JFrame("White power!");
frame.setPreferredSize(new Dimension(250, 250));
frame.getContentPane().setLayout(null);
frame.setIconImage(icon);
frame.addKeyListener(this);
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {}
@Override
public void windowClosing(WindowEvent e) {}
@Override
public void windowClosed(WindowEvent e) {}
@Override
public void windowIconified(WindowEvent e) {
if (hideWhenMinimized)
frame.setVisible(false);
}
@Override
public void windowDeiconified(WindowEvent e) {}
@Override
public void windowActivated(WindowEvent e) {}
@Override
public void windowDeactivated(WindowEvent e) {}
});
JLabel lblImageType = new JLabel("Image Format:");
lblImageType.setBounds(10, 11, 90, 14);
frame.getContentPane().add(lblImageType);
String[] imageTypes = {"PNG", "JPG"};
imageType = new JComboBox<String>(imageTypes);
imageType.setBounds(106, 8, 51, 20);
frame.getContentPane().add(imageType);
JButton btnTakeScreenShot = new JButton("ScreenShot");
btnTakeScreenShot.setBounds(24, 69, 115, 23);
frame.getContentPane().add(btnTakeScreenShot);
btnTakeScreenShot.addActionListener(this);
setTrayIcon();
frame.pack();
frame.setVisible(true);
}
public void setTrayIcon() throws AWTException {
CheckboxMenuItem startup = new CheckboxMenuItem("Run on start-up");
CheckboxMenuItem hide = new CheckboxMenuItem("Hide when minimized");
String[] popupMenuOptions = {"Open", "Exit"};
if (SystemTray.isSupported()) {
SystemTray tray = SystemTray.getSystemTray();
trayIcon.setImageAutoSize(true);
PopupMenu popupMenu = new PopupMenu();
for (String option : popupMenuOptions) {
if (option == "Exit") {
popupMenu.add(startup);
popupMenu.add(hide);
popupMenu.add(option);
} else {
popupMenu.add(option);
}
}
trayIcon.setPopupMenu(popupMenu);
popupMenu.addActionListener(this);
startup.addItemListener(this);
hide.addItemListener(this);
trayIcon.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(true);
}
});
tray.add(trayIcon);
}
}
public void selectArea(final BufferedImage screen) throws Exception {
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()/2), (int)(screen.getHeight()/2)));
JPanel panel = new JPanel(new BorderLayout());
panel.add(screenScroll, BorderLayout.CENTER);
final JLabel selectionLabel = new JLabel("Draw a rectangle");
panel.add(selectionLabel, BorderLayout.SOUTH);
repaint(screen, screenCopy);
screenLabel.repaint();
screenLabel.addMouseMotionListener(new MouseMotionAdapter() {
@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) {
end = me.getPoint();
captureRect = new Rectangle(start, new Dimension(end.x-start.x, end.y-start.y));
try {
paintFinalImage(new BufferedImage((int)screenCopy.getGraphics().getClipBounds(captureRect).getWidth()+1,
(int)screenCopy.getGraphics().getClipBounds(captureRect).getHeight()+1, screen.getType()));
} catch (Exception e) {
e.printStackTrace();
}
repaint(screen, screenCopy);
screenLabel.repaint();
selectionLabel.setText("Rectangle: " + captureRect);
}
});
JOptionPane.showMessageDialog(null, panel, "Select your image", JOptionPane.OK_OPTION, new ImageIcon(""));
uploadImage(screenShot);
System.out.println("Final rectangle: " + screenCopy.getGraphics().getClipBounds(captureRect));
}
public void paintFinalImage(BufferedImage image) throws Exception {
screenShot = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
Graphics2D g = screenShot.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
}
public void repaint(BufferedImage orig, BufferedImage copy) {
Graphics2D g = copy.createGraphics();
g.drawImage(orig, 0, 0, null);
if (captureRect != null) {
g.setColor(Color.BLACK);
g.draw(captureRect);
}
g.dispose();
}
public void uploadImage(BufferedImage image) throws Exception {
String IMGUR_POST_URI = "http://api.imgur.com/2/upload.xml";
String IMGUR_API_KEY = API_KEY;
String readLine = null;
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, imageType.getSelectedItem().toString(), outputStream);
URL url = new URL(IMGUR_POST_URI);
String data = URLEncoder.encode("image", "UTF-8") + "=" + URLEncoder.encode(Base64.encodeBase64String(outputStream.toByteArray()).toString(), "UTF-8");
data += "&" + URLEncoder.encode("key", "UTF-8") + "=" + URLEncoder.encode(IMGUR_API_KEY, "UTF-8");
URLConnection urlConnection = url.openConnection();
urlConnection.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
wr.write(data);
wr.flush();
InputStream inputStream;
if (((HttpURLConnection) urlConnection).getResponseCode() == 400) {
inputStream = ((HttpURLConnection) urlConnection).getErrorStream();
} else {
inputStream = urlConnection.getInputStream();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
readLine = line;
}
wr.close();
reader.close();
} catch(Exception e){
e.printStackTrace();
}
String URL = readLine.substring(readLine.indexOf("<original>") + 10, readLine.indexOf("</original>"));
System.out.println(URL);
Toolkit.getDefaultToolkit().beep();
StringSelection stringSelection = new StringSelection(URL);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
System.out.println(command);
if (command.equalsIgnoreCase("open")) {
frame.setVisible(true);
} else if (command.equalsIgnoreCase("exit")) {
System.exit(-1);
} else if (command.equalsIgnoreCase("screenshot")) {
try {
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
selectArea(screen);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println(e.getItem() + ", " +e.getStateChange());
String itemChanged = e.getItem().toString();
if (itemChanged.equalsIgnoreCase("run on start-up")) {
//TODO
} else if (itemChanged.equalsIgnoreCase("hide when minimized")) {
if (e.getStateChange() == ItemEvent.DESELECTED) {
hideWhenMinimized = false;
} else if (e.getStateChange() == ItemEvent.SELECTED) {
hideWhenMinimized = true;
}
}
}
@Override
public void keyTyped(KeyEvent e) {
System.out.println("KeyTyped: "+e.getKeyCode());
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void nativeKeyPressed(NativeKeyEvent e) {
}
@Override
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("KeyReleased: "+e.getKeyCode());
System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
if (e.getKeyCode() == 154) {
try {
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
final BufferedImage screen = robot.createScreenCapture(new Rectangle(screenSize));
selectArea(screen);
frame.setVisible(true);
} catch(Exception e1) {
e1.printStackTrace();
}
}
}
@Override
public void nativeKeyTyped(NativeKeyEvent e) {
}
}
答案 0 :(得分:2)
我建议您简化问题以解决问题。创建一个小的可编译和可运行程序,它没有当前代码的所有包袱,但其唯一目标是显示图像,并让用户选择该图像的子部分。然后,如果您的尝试失败,您可以在此处发布您的尝试,我们实际上可以运行它并理解它,并希望能够解决它。
例如,这里有一小部分可编译和可运行的代码,它使用MouseListener来选择图像的一小部分。也许你可以从中得到一些想法:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class ImagePlay extends JPanel {
public static final String IMAGE_PATH = "http://upload.wikimedia.org/wikipedia/" +
"commons/thumb/3/39/European_Common_Frog_Rana_temporaria.jpg/" +
"800px-European_Common_Frog_Rana_temporaria.jpg";
private static final Color RECT_COLOR = new Color(180, 180, 255);
private BufferedImage img = null;
Point p1 = null;
Point p2 = null;
public ImagePlay() {
URL imgUrl;
try {
imgUrl = new URL(IMAGE_PATH);
img = ImageIO.read(imgUrl );
ImageIcon icon = new ImageIcon(img);
JLabel label = new JLabel(icon) {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
myLabelPaint(g);
}
};
setLayout(new BorderLayout());
add(new JScrollPane(label));
MouseAdapter mAdapter = new MyMouseAdapter();
label.addMouseListener(mAdapter);
label.addMouseMotionListener(mAdapter);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void myLabelPaint(Graphics g) {
if (p1 != null && p2 != null) {
int x = Math.min(p1.x, p2.x);
int y = Math.min(p1.y, p2.y);
int width = Math.abs(p1.x - p2.x);
int height = Math.abs(p1.y - p2.y);
g.setXORMode(Color.DARK_GRAY);
g.setColor(RECT_COLOR);
g.drawRect(x, y, width, height);
}
}
private class MyMouseAdapter extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
p1 = e.getPoint();
p2 = null;
repaint();
}
@Override
public void mouseDragged(MouseEvent e) {
p2 = e.getPoint();
repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
p2 = e.getPoint();
repaint();
int x = Math.min(p1.x, p2.x);
int y = Math.min(p1.y, p2.y);
int width = Math.abs(p1.x - p2.x);
int height = Math.abs(p1.y - p2.y);
BufferedImage smlImg = img.getSubimage(x, y, width, height);
ImageIcon icon = new ImageIcon(smlImg);
JLabel label = new JLabel(icon);
JOptionPane.showMessageDialog(ImagePlay.this, label, "Selected Image",
JOptionPane.PLAIN_MESSAGE);
}
}
private static void createAndShowGui() {
ImagePlay mainPanel = new ImagePlay();
JFrame frame = new JFrame("ImagePlay");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
它使用在线获取的公开图像,添加到JLabel的MouseListener,以及JLabel覆盖其paintComponent(...)
方法,以显示MouseListener / Adapter的引导线。它通过BufferedImage的getSubimage(...)
方法创建子图像,然后将其显示在JOptionPane中,但如果需要,保存图像将是微不足道的。