Java Robot应用示例之机器人功能,javarobot

这是一篇入门级文章,高手请略过。

java图像处理干货篇

Java Robot应用示例之机器人功能,javarobot

很多时候,我们希望能够实现自动测试,自动演示功能,或者是其它的一些鼠标和键盘控制的应用(比如帮人点击广告赚利润等)。出于这样的目的,自从JDK1.3开始,它就为我们提供了一个用来产生本机输入事件的机器人类
— java.awt.Robot. 

  下面我来详细介绍Robot的功能及应用示例:

一、Robot主要的功能

  1. BufferedImage createScreenCapture(Rectangle screenRect) 

说明:该方法提供类似于键盘上的PrintScreen键的功能,将指定矩形区域内的屏幕像素copy下来产生一个BufferedImage。
应用:我们可以将这个方法用在图形程序中,或是用它来实现远端屏幕传输,可做成远端电脑监控程序等.

  1. void delay(int ms)

说明:用来将当前的程序(thread)休眠(sleep)若干毫秒(ms)。
应用:可用来控制程序的延时。这个一般是必须的,因为你在两次间隔操作中肯定有延时。

  1. Color getPixelColor(int x, int y)

说明:取得给定屏幕坐标像素位置的颜色值。
应用:就是取颜色RGB值,就不多说了。

  1. void keyPress(int keycode)
     void keyRelease(int keycode)

说明:这两个方法的作用一看便知,用来产生指定键的按键按下与抬起动作,相当于Win32
API的keyb_event函数,即模拟键盘操作咯,具体keycode值就是KeyEvent.VK_C、KeyEvent.VK_D、KeyEvent.VK_CONTROL什么的,具体应用时直接看Eclipse提示就知道了。
应用:可用于程序的自动演示、测试等,非常有用。

  1. void mouseMove(int x, int y)

说明:将鼠标光标移动到指定的屏幕坐标。
应用:可用于程序的自动演示、测试等,配合其他的方法使用,是不可缺少的。

  1. void mousePress(int buttons)
     void mouseRelease(int buttons)
     void mouseWheel(int wheelAmt)

说明:上面的三种方法,产生指定鼠标按钮的按下,抬起,及滚轮动作,就是模拟鼠标操作咯,具体buttons的值有InputEvent.BUTTON1_MASK(鼠标左键)、InputEvent.BUTTON3_MASK(鼠标右键,如果是双键鼠标,请改用InputEvent.BUTTON2_MASK)等。

应用:一样也可用于程序的自动演示、测试等,配合其他方法使用,很重要。

二、应用实例

我写了两个比较小的应用实例,一个是简单的模拟测试,一个是自动点击广告赚利润的,下面分别演示。

首先编写一些公用的方法Common.java

package com.alexia; 

import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.event.InputEvent; 
import java.awt.event.KeyEvent; 
import java.awt.image.BufferedImage; 

import javax.swing.Icon; 
import javax.swing.ImageIcon; 

/** 
 * @description Robot帮助类,实现基本的功能 
 * @author Alexia 
 * @date 2013/5/18 
 * 
 */ 
public class Common { 

  /** 
   * 鼠标单击(左击),要双击就连续调用 
   * 
   * @param r 
   * @param x 
   *      x坐标位置 
   * @param y 
   *      y坐标位置 
   * @param delay 
   *      该操作后的延迟时间 
   */ 
  public static void clickLMouse(Robot r, int x, int y, int delay) { 
    r.mouseMove(x, y); 
    r.mousePress(InputEvent.BUTTON1_MASK); 
    r.delay(10); 
    r.mouseRelease(InputEvent.BUTTON1_MASK); 
    r.delay(delay); 

  } 

  /** 
   * 鼠标右击,要双击就连续调用 
   * 
   * @param r 
   * @param x 
   *      x坐标位置 
   * @param y 
   *      y坐标位置 
   * @param delay 
   *      该操作后的延迟时间 
   */ 
  public static void clickRMouse(Robot r, int x, int y, int delay) { 
    r.mouseMove(x, y); 
    r.mousePress(InputEvent.BUTTON3_MASK); 
    r.delay(10); 
    r.mouseRelease(InputEvent.BUTTON3_MASK); 
    r.delay(delay); 

  } 

  /** 
   * 键盘输入(一次只能输入一个字符) 
   * 
   * @param r 
   * @param ks 
   *      键盘输入的字符数组 
   * @param delay 
   *      输入一个键后的延迟时间 
   */ 
  public static void pressKeys(Robot r, int[] ks, int delay) { 
    for (int i = 0; i < ks.length; i++) { 
      r.keyPress(ks[i]); 
      r.delay(10); 
      r.keyRelease(ks[i]); 
      r.delay(delay); 
    } 
  } 

  /** 
   * 复制 
   * 
   * @param r 
   * @throws InterruptedException 
   */ 
  void doCopy(Robot r) throws InterruptedException { 
    Thread.sleep(3000); 
    r.setAutoDelay(200); 
    r.keyPress(KeyEvent.VK_CONTROL); 
    r.keyPress(KeyEvent.VK_C); 
    r.keyRelease(KeyEvent.VK_CONTROL); 
    r.keyRelease(KeyEvent.VK_C); 
  } 

  /** 
   * 粘贴 
   * 
   * @param r 
   * @throws InterruptedException 
   */ 
  void doParse(Robot r) throws InterruptedException { 
    r.setAutoDelay(500); 
    Thread.sleep(2000); 
    r.mouseMove(300, 300); 
    r.mousePress(InputEvent.BUTTON1_MASK); 
    r.mouseRelease(InputEvent.BUTTON1_MASK); 
    r.keyPress(KeyEvent.VK_CONTROL); 
    r.keyPress(KeyEvent.VK_V); 
    r.keyRelease(KeyEvent.VK_CONTROL); 
    r.keyRelease(KeyEvent.VK_V); 
  } 

  /** 
   * 捕捉全屏慕 
   * 
   * @param r 
   * @return 
   */ 
  public Icon captureFullScreen(Robot r) { 
    BufferedImage fullScreenImage = r.createScreenCapture(new Rectangle( 
        Toolkit.getDefaultToolkit().getScreenSize())); 
    ImageIcon icon = new ImageIcon(fullScreenImage); 
    return icon; 
  } 

  /** 
   * 捕捉屏幕的一个矫形区域 
   * 
   * @param r 
   * @param x 
   *      x坐标位置 
   * @param y 
   *      y坐标位置 
   * @param width 
   *      矩形的宽 
   * @param height 
   *      矩形的高 
   * @return 
   */ 
  public Icon capturePartScreen(Robot r, int x, int y, int width, int height) { 
    r.mouseMove(x, y); 
    BufferedImage fullScreenImage = r.createScreenCapture(new Rectangle( 
        width, height)); 
    ImageIcon icon = new ImageIcon(fullScreenImage); 
    return icon; 
  } 

} 

在示例之前,注意屏幕坐标位置如何确定,我是下载了一个小工具,用起来十分方便,建议大家使用

  1. 简单的模拟测试

    package com.alexia;

    import java.awt.;
    import java.awt.event.
    ;
    import javax.swing.JOptionPane;

    public class SimpleTest {

    public static void main(String[] args) throws Exception {

     final Robot rb = new Robot(); 
    
     new Thread() { 
       public void run() { 
         rb.delay(2000); // 模拟回车 
         rb.keyPress(KeyEvent.VK_ENTER); 
         rb.keyRelease(KeyEvent.VK_ENTER); 
       } 
     }.start(); 
    
     rb.delay(3000); 
    
     // 设置开始菜单的大概位置 
     int x = 40; 
     int y = Toolkit.getDefaultToolkit().getScreenSize().height - 10; // 鼠标移动到开始菜单, 
     rb.mouseMove(x, y); 
     rb.delay(500); 
    
     // 单击开始菜单 
     Common.clickLMouse(rb, x, y, 500); 
    
     rb.delay(1000); 
    
     // 运行CMD命令cmd enter 
     int[] ks = { KeyEvent.VK_C, KeyEvent.VK_M, 
         KeyEvent.VK_D, KeyEvent.VK_ENTER, }; 
     Common.pressKeys(rb, ks, 500); 
     rb.mouseMove(400, 400); 
     rb.delay(500); 
    
     // 运行DIR命令dir enter 
     ks = new int[] { KeyEvent.VK_D, KeyEvent.VK_I, KeyEvent.VK_R, 
         KeyEvent.VK_ENTER }; 
     Common.pressKeys(rb, ks, 500); 
     rb.delay(1000); 
    
     // 运行CLS命令cls enter 
     ks = new int[] { KeyEvent.VK_C, KeyEvent.VK_L, KeyEvent.VK_S, 
         KeyEvent.VK_ENTER }; 
     Common.pressKeys(rb, ks, 500); 
     rb.delay(1000); 
    
     // 运行EXIT命令exit enter 
     ks = new int[] { KeyEvent.VK_E, KeyEvent.VK_X, KeyEvent.VK_I, 
         KeyEvent.VK_T, KeyEvent.VK_ENTER }; 
     Common.pressKeys(rb, ks, 500); 
     rb.delay(1000); 
    
     // 右键测试 
     x = Toolkit.getDefaultToolkit().getScreenSize().width - 50; 
     Common.clickRMouse(rb, x, y, 500); 
    
     new Thread() { 
       public void run() { 
         rb.delay(1000); // 回车 
         rb.keyPress(KeyEvent.VK_ENTER); 
         rb.keyRelease(KeyEvent.VK_ENTER); 
       } 
     }.start(); 
    
     JOptionPane.showMessageDialog(null, "演示完毕!"); 
    

    }
    }

  2. 点击网易广告赚取微薄利润

    package com.alexia;

    import java.awt.AWTException;
    import java.awt.Desktop;
    import java.awt.Robot;
    import java.awt.event.KeyEvent;
    import java.io.IOException;
    import java.net.URI;
    import java.util.Random;

    public class AutoClickAds {

    private Robot robot;

    private volatile boolean stop = false;

    /* Creates a new instance of Main /

    public AutoClickAds() {

     try { 
    
       robot = new Robot(); 
    
     } catch (AWTException ex) { 
    
       ex.printStackTrace(); 
    
     } 
    

    }

    public void init() {

     robot.delay(3000); 
    
     System.out.println("Click Ads start"); 
    
     // 在新的浏览器窗口或在已有的浏览器窗口打开指定的URL(JDK 1.6以上) 
     Desktop desktop = Desktop.getDesktop(); 
     if (Desktop.isDesktopSupported() && desktop.isSupported(Desktop.Action.BROWSE)) { 
       URI uri = URI.create("http://lanxuezaipiao.blog.163.com/"); 
       try { 
         desktop.browse(uri); 
       } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
       } 
     } 
    
     try { 
       run(); 
     } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
     } 
    
     stop(); 
    
     System.out.println("Click Ads stoped"); 
    

    }

    public void run() throws InterruptedException {

     int count = 1; 
    
     while (!stop) { 
       robot.delay(8000); 
    
       int x = 576; 
       int y = 567; 
       Random r = new Random(); 
    
       Common.clickLMouse(robot, x, y, 3000); 
    
       // 输入向下箭头,实现翻页 
       int[] ks = { KeyEvent.VK_DOWN }; 
       for (int i = 0; i < 10; i++) 
         Common.pressKeys(robot, ks, 0); 
    
       int[][] a = { { 500, 103 }, { 500, 163 }, { 500, 223 }, 
           { 500, 283 }, { 500, 343 }, { 500, 403 }, { 500, 463 }, 
           { 500, 523 }, { 500, 583 }, { 500, 643 }, }; 
       int b = r.nextInt(5); 
       x = a[b][0]; 
       y = a[b][1]; 
    
       Common.clickLMouse(robot, x, y, 1000); 
    
       // 输入向下箭头,实现翻页 
       for (int i = 0; i < 500; i++) 
         Common.pressKeys(robot, ks, 0); 
    
       // 输入向下箭头,实现翻页 
       int[] kups = { KeyEvent.VK_UP }; 
       for (int i = 0; i < 3; i++) 
         Common.pressKeys(robot, kups, 0); 
    
       x = 900; 
       y = 210; 
       Common.clickLMouse(robot, x, y, 3000); 
    
       x =1090; 
       y =15; 
       Common.clickLMouse(robot, x, y, 3000); 
    
       x = 900; 
       y = 135; 
       Common.clickLMouse(robot, x, y, 3000); 
    
       System.out.println("成功点击第" + count + "个广告!"); 
     } 
    

    }

    public synchronized void stop() {

     stop = true; 
    

    }

    /**

    * * @param args the command line arguments 
    * 
    * @throws InterruptedException 
    */ 
    

    public static void main(String[] args) throws InterruptedException {

     AutoClickAds mc = new AutoClickAds(); 
     mc.init(); 
    

    }
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持帮客之家。

Robot应用示例之机器人功能,javarobot
很多时候,我们希望能够实现自动测试,自动演示功能,或者是其它的一些鼠标和键盘控制的应用…

在这篇文章中我们将学习如何用 Java
对图像进行剪裁并将剪裁出来的部分单独保存到文件中。

绘制图像

绘制图像主要用到的是Graphics类中drawImage方法,当然Graphics2D中也有相应的方法

主要的用法:

  • public abstract boolean drawImage(Image img,x,y,ImageObserver observer):img是Image对象,x,y起始坐标,observer是观察对象
  • drawImage(Image img,int x,int y,int width,int height,Imageobersver observer):widthheight是指定图像的宽度和高度,主要的作用是放大和缩小图像
  • drawImage(Image img,int dx1,int dy1,int dx2,int dx2,int sx1,int sy1,int sx2,int sy2,ImageObserver observer):主要用来翻转图形,通过互换源矩形的第一个和第二个角的x坐标可以实现水平翻转,通过互换源矩形的第一个和第二个角的y坐标可以实现垂直翻转

我们将通过以下步骤来学习:

翻转图像

package com.zzk;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PartImageFrame extends JFrame {
    private Image img = null;  // 声明图像对象
    private PartImagePanel imagePanel = null;  // 声明图像面板对象
    private int dx1, dy1, dx2, dy2;   // 目标矩形第一个角与第二个角的X、Y坐标
    private int sx1, sy1, sx2, sy2;   // 源矩形第一个角与第二个角的X、Y坐标
    public static void main(String args[]) {
        PartImageFrame frame = new PartImageFrame();
        frame.setVisible(true);
    }
    public PartImageFrame() {
        super();
        URL imgUrl = PartImageFrame.class.getResource("/img/image.jpg");// 获取图片资源的路径
        img = Toolkit.getDefaultToolkit().getImage(imgUrl); // 获取图像资源
        dx2 = sx2 = 340; // 初始化图像大小
        dy2 = sy2 = 200; // 初始化图像大小
        imagePanel = new PartImagePanel();  // 创建图像面板对象
        this.setBounds(200, 160, 355, 276); // 设置窗体大小和位置
        this.add(imagePanel); // 在窗体中部位置添加图像面板对象
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体关闭模式
        this.setTitle("翻转图像"); // 设置窗体标题
        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.SOUTH);
        final JButton btn_h = new JButton();
        btn_h.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                // 下面3行代码用于交换sx1和sx2的值
                int x = sx1;
                sx1 = sx2;
                sx2 = x;
                imagePanel.repaint();  // 重新调用面板类的paint()方法
            }
        });
        btn_h.setText("水平翻转");
        panel.add(btn_h);
        final JButton btn_v = new JButton();
        btn_v.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                // 下面3行代码用于交换sy1和sy2的值
                int y = sy1;
                sy1 = sy2;
                sy2 = y;
                imagePanel.repaint();// 重新调用面板类的paint()方法
            }
        });
        btn_v.setText("垂直翻转");
        panel.add(btn_v);
    }
    // 创建面板类
    class PartImagePanel extends JPanel {
        public void paint(Graphics g) {
            g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除绘图上下文的内容
            g.drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, this);// 绘制图像

        }
    }
}
  1. 输入图像,指定要处理的图像路径
  2. 允许用户拖放要剪裁的部分
  3. 选择后使用 Robot 类来确定剪裁部分的坐标
  4. 剪裁所选图像并保持

旋转图像

主要用到的是Graphics2D类中的rotate函数,定义如下:public abstract void rotate(double theta):
theta是角度,以弧度为单位
代码如下

package com.zzk;
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class RotateImageFrame extends JFrame {
    private Image img = null;
    private RotatePanel rotatePanel = null;
    public RotateImageFrame() {
        URL imgUrl = RotateImageFrame.class.getResource("/img/image.jpg");// 获取图片资源的路径
        img = Toolkit.getDefaultToolkit().getImage(imgUrl);   // 获取图片资源
        rotatePanel = new RotatePanel();  // 创建旋转图像的面板对象
        this.setBounds(150, 120, 380, 310);                 // 设置窗体大小和位置
        add(rotatePanel);// 在窗体上放置图像面板
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  // 设置窗体关闭模式
        this.setTitle("旋转图像");                     // 设置窗体标题
    }
    public static void main(String[] args) {
        new RotateImageFrame().setVisible(true);
    }
    class RotatePanel extends JPanel {
        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;         // 获得Graphics2D对象
            g2.drawImage(img, 80, 10, 260, 150, this);      // 绘制指定大小的图片
            g2.rotate(Math.toRadians(10));                 // 将图片旋转10度
            g2.drawImage(img, 80, 10, 260, 150, this);      // 绘制指定大小的图片
            g2.rotate(Math.toRadians(10));                // 将图片旋转10度
            g2.drawImage(img, 80, 10, 260, 150, this);      // 绘制指定大小的图片
        }
    }
}

接下来我们开始编码部分。

倾斜图像

主要用到的是Graphics2D中的shear函数定义如:public abstract void shear(doubel shx,double shy):shx是在正x轴上移动坐标的乘数,它可以作为其纵坐标的值,shy是在正y轴方形移动坐标的乘数,它可以作为其x坐标的函数。
*本人的理解:
倾斜画布,如果shx>0就是向正方向平移,平移的长度为shx
height(图形纵坐标的值,如果是矩形就是乘以矩形的高)
相同的对于shy是乘以矩形宽

package com.zzk;
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class ShearImageFrame extends JFrame {
    private Image img;
    private ShearImagePanel canvasPanel = null;
    public ShearImageFrame() {
        URL imgUrl = ShearImageFrame.class.getResource("/img/image.jpg");// 获取图片资源的路径
        img = Toolkit.getDefaultToolkit().getImage(imgUrl);  // 获取图片资源
        canvasPanel = new ShearImagePanel();     // 创建绘制倾斜图像的面板对象
        this.setBounds(100, 100, 360, 240);                // 设置窗体大小和位置
        add(canvasPanel);// 在窗体上添加面板对象
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体关闭模式
        this.setTitle("倾斜图像");                    // 设置窗体标题
    }
    public static void main(String[] args) {
        new ShearImageFrame().setVisible(true);
    }
    class ShearImagePanel extends JPanel {// 绘制倾斜图像的面板类
        public void paint(Graphics g) {
            Graphics2D g2=(Graphics2D) g;// 获得Graphics2D对象
            g2.shear(0, -0.5);// 倾斜图像
            g2.drawImage(img, 10, 20, 220, 160, this);     // 绘制指定大小的图片
        }
    }
}

Listing1: 引入的类

裁剪图片

public BufferedImage createScreenCapture(Rectangle screenRect):返回的是一个BufferedImage对象,参数是Rectangle对象,这个函数是Robot类中的,主要用于裁剪图形

package com.zzk;
import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

public class CutImageFrame extends JFrame {
    private Image img = null; // 声明图像对象
    private OldImagePanel oldImagePanel = null; // 声明图像面板对象
    private int pressPanelX = 0, pressPanelY = 0;// 鼠标按下点的X、Y坐标 
    private int pressX = 0, pressY = 0;// 鼠标按下点在屏幕上的X、Y坐标
    private int releaseX = 0, releaseY = 0;// 鼠标释放点在屏幕上的X、Y坐标
    private Robot robot = null;  // 声明Robot对象
    private BufferedImage buffImage = null; // 声明缓冲图像对象
    private CutImagePanel cutImagePanel = new CutImagePanel(); // 创建绘制裁剪结果的面板
    private boolean flag = false;  // 声明标记变量,为true时显示选择区域的矩形,否则不显示

    public static void main(String args[]) {
        CutImageFrame frame = new CutImageFrame();
        frame.setVisible(true);
    }

    public CutImageFrame() {
        super();
        URL imgUrl = CutImageFrame.class.getResource("/img/image.jpg");// 获取图片资源的路径
        img = Toolkit.getDefaultToolkit().getImage(imgUrl); // 获取图像资源
        oldImagePanel = new OldImagePanel(); // 创建图像面板对象
        this.setBounds(200, 160, 355, 276); // 设置窗体大小和位置
        final JSplitPane splitPane = new JSplitPane();
        splitPane.setDividerLocation((this.getWidth() / 2) - 10);
        getContentPane().add(splitPane, BorderLayout.CENTER);
        splitPane.setLeftComponent(oldImagePanel);
        splitPane.setRightComponent(cutImagePanel);
        oldImagePanel.addMouseListener(new MouseAdapter() {
            public void mousePressed(final MouseEvent e) {  // 鼠标键按下事件
                pressPanelX = e.getX(); // 获得鼠标按下点的X坐标 
                pressPanelY = e.getY();// 获得鼠标按下点的Y坐标 
                pressX = e.getXOnScreen() + 1;// 鼠标按下点在屏幕上的X坐标加1,即去除选择线
                pressY = e.getYOnScreen() + 1;// 鼠标按下点在屏幕上的Y坐标加1,即去除选择线
                flag = true;// 为标记变量赋值为true
            }

            public void mouseReleased(final MouseEvent e) { // 鼠标键释放事件
                releaseX = e.getXOnScreen() - 1;// 鼠标释放点在屏幕上的X坐标减1,即去除选择线
                    releaseY = e.getYOnScreen() - 1;// 鼠标释放点在屏幕上的Y坐标减1,即去除选择线
                    try {
                    robot = new Robot();// 创建Robot对象
                    if (releaseX - pressX > 0 && releaseY - pressY > 0) {
                        Rectangle rect = new Rectangle(pressX, pressY, releaseX
                                - pressX, releaseY - pressY);// 创建Rectangle对象
                        buffImage = robot.createScreenCapture(rect);// 获得缓冲图像对象
                        cutImagePanel.repaint(); // 调用CutImagePanel面板的paint()方法
                    }
                } catch (AWTException e1) {
                    e1.printStackTrace();
                }
                flag = false;// 为标记变量赋值为false
            }
        });
        oldImagePanel.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(final MouseEvent e) {// 鼠标拖动事件
                if (flag) {
                    releaseX = e.getXOnScreen();// 获得鼠标释放点在屏幕上的X坐标
                    releaseY = e.getYOnScreen();// 获得鼠标释放点在屏幕上的Y坐标
                    oldImagePanel.repaint();// 调用OldImagePanel面板的paint()方法
                }
            }
        });
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体关闭模式
        this.setTitle("裁剪图片"); // 设置窗体标题
    }




    class OldImagePanel extends JPanel {// 创建绘制原图像的面板类

        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);// 绘制图像
            g2.setColor(Color.WHITE);
            if (flag) {
                float[] arr = {5.0f}; // 创建虚线模式的数组
                BasicStroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
                        BasicStroke.JOIN_BEVEL, 1.0f, arr, 0); // 创建宽度是1的平头虚线笔画对象
                g2.setStroke(stroke);// 设置笔画对象
                g2.drawRect(pressPanelX, pressPanelY, releaseX - pressX,
                        releaseY - pressY);// 绘制矩形选区
            }
        }
    }

    class CutImagePanel extends JPanel {// 创建绘制裁剪结果的面板类

        public void paint(Graphics g) {
            g.clearRect(0, 0, this.getWidth(), this.getHeight());// 清除绘图上下文的内容
            g.drawImage(buffImage, 0, 0, releaseX - pressX, releaseY - pressY,
                    this);// 绘制图像
        }




    }
}
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

调整图片的亮度

RescaleOp类中的filter方法原缓冲图像进行重缩放,定义如下
public abstract BufferedImage filter(BufferedImage src,BufferedImage dst):src是要过滤的源对象,dst是目标对象,或则为null

package com.zzk;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageBrightenFrame extends JFrame {
    private BufferedImage image;// 用于调整亮度的缓冲图像对象
    private BufferedImage oldImage;// 用于存放调整亮度之前的原缓冲图像对象
    private ImageBrightenPanel imageBrightenPanel = new ImageBrightenPanel();

    public static void main(String args[]) {
        ImageBrightenFrame frame = new ImageBrightenFrame();
        frame.setVisible(true);
    }

    public ImageBrightenFrame() {
        super();
        setBounds(100, 100, 357, 276);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("调整图片的亮度");
        Image img = null;
        try {
            img = ImageIO.read(new File("src/img/image.jpg"));  // 创建图像对象
        } catch (IOException e) {
            e.printStackTrace();
        }
        image = new BufferedImage(img.getWidth(this), img.getHeight(this),
        BufferedImage.TYPE_INT_RGB);// 创建缓冲图像对象
        image.getGraphics().drawImage(img, 0, 0, null);// 在缓冲图像对象上绘制图像
        oldImage = image;// 存储原来的图像对象,用于以后的恢复操作
        getContentPane().add(imageBrightenPanel, BorderLayout.CENTER);

        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.SOUTH);

        final JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                float a = 1.0f;// 定义缩放因子
                float b = 5.0f;// 定义偏移量
                RescaleOp op = new RescaleOp(a,b,null);// 创建具有指定缩放因子和偏移量的 RescaleOp对象
                image = op.filter(image, null);// 对源图像中的数据进行逐像素重缩放,达到变亮的效果
                repaint();// 重新绘制图像
            }
        });
        button.setText("变    亮");
        panel.add(button);

        final JButton button_3 = new JButton();
        button_3.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                float a = 1.0f;// 定义缩放因子
                float b = -5.0f;// 定义偏移量
                RescaleOp op = new RescaleOp(a,b,null);// 创建具有指定缩放因子和偏移量的 RescaleOp对象
                image = op.filter(image, null);// 对源图像中的数据进行逐像素重缩放,达到变暗的效果
                repaint();// 重新绘制图像
            }
        });
        button_3.setText("变    暗");
        panel.add(button_3);

        final JButton button_2 = new JButton();
        button_2.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                image = oldImage;  // 获得变亮前的图像
                imageBrightenPanel.repaint();// 重新绘制原图像,即恢复为变亮前的图像
            }
        });
        button_2.setText("恢    复");
        panel.add(button_2);

        final JButton button_1 = new JButton();
        button_1.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                System.exit(0);
            }
        });
        button_1.setText("退    出");
        panel.add(button_1);
  }

    class ImageBrightenPanel extends JPanel {
        public void paint(Graphics g) {
            if (image != null) {
                g.drawImage(image, 0, 0, null);  // 将缓冲图像对象绘制到面板上
            }
        }
    }
}

补充说明:这里的RescaleOp类可以调整色数,其原理是每一个样本值乘以一个缩放因子然后加上偏移量就是缩放的数,如果要变亮的话就将偏移量为正,反之为负,这里将缩放因子设置为1.0f是因为不想那么快速的变亮,如果你设置的大一点,就会很快变得很亮,反之亦然

说明:

转换彩色图片为灰色图片

主要使用ColorConvertOp类,其构造函数如下
public ColorConvertOp(ColorSpace src,ColorSpace dst,RenderingHints hints):src是原颜色空间对象,dst是目标颜色空间对象,hints是用于控制颜色转换的RenderingHints对象,可以为null
使用ColorConvertOp类中的filter方法将彩色图像转换成灰色图像,定义如下:
public final BufferedImage filter(BufferedImage src,BufferedImage dst):scr要过滤的对象,dst目标空间对象

package com.zzk;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MultiColorToGrayFrame extends JFrame {
    private BufferedImage image;
    private ColorToGrayPanel colorToGrayPanel = new ColorToGrayPanel();

    public static void main(String args[]) {
        MultiColorToGrayFrame frame = new MultiColorToGrayFrame();
        frame.setVisible(true);
    }

    public MultiColorToGrayFrame() {
        super();
        setBounds(100, 100, 357, 276);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("彩色图像转换为灰度");
        Image img = null;
        try {
            img = ImageIO.read(new File("src/img/image.jpg"));  // 创建图像对象
        } catch (IOException e) {
            e.printStackTrace();
        }
        image = new BufferedImage(img.getWidth(this), img.getHeight(this),
                BufferedImage.TYPE_INT_RGB);// 创建缓冲图像对象
        image.getGraphics().drawImage(img, 0, 0, null);// 在缓冲图像对象上绘制图像

        getContentPane().add(colorToGrayPanel, BorderLayout.CENTER);

        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.SOUTH);

        final JButton button = new JButton();
        button.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                ColorSpace colorSpace1 = ColorSpace.getInstance(ColorSpace.CS_GRAY);// 创建内置线性为灰度的颜色空间
                ColorSpace colorSpace2 = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);// 创建内置线性为 RGB的颜色空间
                ColorConvertOp op = new ColorConvertOp(colorSpace1,colorSpace2,
                        null);// 创建进行颜色转换的对象
                image = op.filter(image, null);// 对缓冲图像进行颜色转换
            repaint();// 重新绘制图像
        }
        });
        button.setText("转换为灰度");
        panel.add(button);

        final JButton button_1 = new JButton();
        button_1.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                System.exit(0);
            }
        });
        button_1.setText("退    出");
        panel.add(button_1);
    }

    class ColorToGrayPanel extends JPanel {
        public void paint(Graphics g) {
            if (image != null) {
                g.drawImage(image, 0, 0, null);  // 将缓冲图像对象绘制到面板上
            }
        }
    }
}

补充说明:这里的image.getGraphics().drawImage(img, 0, 0, null)是必须有的,这是绘制对缓冲图像的绘制

  1. Graphics 类包含绘制矩形的方法
  2. 我们使用 Rectangle 类作为拖拉的矩形区域以作剪裁
  3. Robot 类用于捕获屏幕截图
  4. 使用鼠标侦听器来获取鼠标的拖拉时间
  5. Robot 类使用 BufferedImage 来做图像处理
  6. File 类用于打开图像文件
  7. ImageIO 类用于将图像写到 png 或者 jpg 图像文件中
  8. JFrame 用于显示界面

总结:

从文件中读取图像的方法

  • URL imgUrl =
    CutImageFrame.class.getResource(“/img/image.jpg”);//得到的是URL
    img = Toolkit.getDefaultToolkit().getImage(imgUrl);
    //得到的是Image对象,同样的想要得到BufferedImage对象可以进行转
  • Image img=ImageIo(new File("path"));这里得到的是Image对象,如果想要得到BufferedImage对象,可以用BufferedImage的构造方法BufferedImage(int
    width,int height,)

现在我们编写包含 main 方法的入口类

Listing2: 入口类

public class CropImage extends JFrame implements MouseListener, MouseMotionListener
{
    int drag_status=0,c1,c2,c3,c4;
public static void main(String args[])
{
    new CropImage().start();
}

说明:

  1. 编写了一个名为 CropImage 的类
  2. 该类扩展了 JFrame 以实现 frame 的所有功能
  3. 实现了不同的鼠标事件侦听器以便知道用户什么时候开始拖动鼠标指针
  4. drag_status 变量用于保存鼠标开始拖动时的坐标
  5. 我们定义了 main 方法去调用一个 start 方法,这个方法将在下面定义

接下来是 start 方法

Listing 2

public void start()
{
    ImagePanel im=new ImagePanel("F:\Wallpaper\wallpapers\1.jpg");
    add(im);
    setSize(400,400);
    setVisible(true);
    addMouseListener(this);
    addMouseMotionListener( this );
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}

说明:

  1. 我们定义一个名为 ImagePanel 的类,使用要处理的图像作为参数
  2. 在 JFrame 中放置这个要显示图片的 ImagePanel,并开始侦听鼠标事件

下面我们定义用于处理鼠标事件的方法

Listing 3: 鼠标事件处理函数

@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

@Override
public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
    repaint();
    c1=arg0.getX();
    c2=arg0.getY();
}

@Override
public void mouseReleased(MouseEvent arg0) {
    repaint();
    if(drag_status==1)
    {
    c3=arg0.getX();
    c4=arg0.getY();
    try
    {
    draggedScreen();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    }
}

@Override
public void mouseDragged(MouseEvent arg0) {
    repaint();
    drag_status=1;
    c3=arg0.getX();
    c4=arg0.getY();
}

@Override
public void mouseMoved(MouseEvent arg0) {

}

public void paint(Graphics g)
{
    super.paint(g);
    int w = c1 - c3;
    int h = c2 - c4;
    w = w * -1;
    h = h * -1;
    if(w<0)
        w = w * -1;
    g.drawRect(c1, c2, w, h);

}

说明:

  1. 当鼠标按下时存储当前坐标到 c1 和 c2
  2. 当鼠标按下并开始拖动时将拖动状态变量 drag_status 设置为 true
  3. 到鼠标按键松开时表示图像剪裁区域已经选择完毕,调用 draggedscreen
    方法
  4. paint
    方法用于拖动时候的矩形显示,通过当前坐标和初始记录的坐标来绘制矩形

下面是 draggedscreen 方法的代码

Listing 4: draggedScreen 方法

public void draggedScreen()throws Exception
{
        int w = c1 - c3;
        int h = c2 - c4;
        w = w * -1;
        h = h * -1;
        Robot robot = new Robot();
        BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2,w,h));
        File save_path=new File("screen1.jpg");
        ImageIO.write(img, "JPG", save_path);
    System.out.println("Cropped image saved successfully.");
}}

说明:

  1. 首先计算图像的高度和宽度
  2. 使用 Robot 类来对剪裁的区域进行截图并保持到另外一个文件 screen1.jpg

完整的代码

Listing 5: ImagePanel.java

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

    class ImagePanel extends JPanel {

          private Image img;

          public ImagePanel(String img) {
            this(new ImageIcon(img).getImage());
          }

          public ImagePanel(Image img) {
            this.img = img;
            Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
           // Dimension size = new Dimension(10,10);
            setPreferredSize(size);
            setMinimumSize(size);
            setMaximumSize(size);
            setSize(size);
            setLayout(null);
          }

          public void paintComponent(Graphics g) {
            g.drawImage(img, 0, 0, null);
          }

        }

Listing 6:CropImage.java

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;

public class CropImage extends JFrame implements MouseListener, MouseMotionListener
{
    int drag_status=0,c1,c2,c3,c4;
public static void main(String args[])
{
    new CropImage().start();
}
public void start()
{
    ImagePanel im=new ImagePanel("F:\Wallpaper\wallpapers\1.jpg");
    add(im);
    setSize(400,400);
    setVisible(true);
    addMouseListener(this);
    addMouseMotionListener( this );
    setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void draggedScreen()throws Exception
{
        int w = c1 - c3;
        int h = c2 - c4;
        w = w * -1;
        h = h * -1;
        Robot robot = new Robot();
        BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2,w,h));
        File save_path=new File("screen1.jpg");
        ImageIO.write(img, "JPG", save_path);
    System.out.println("Cropped image saved successfully.");
}
@Override
public void mouseClicked(MouseEvent arg0) {
}

@Override
public void mouseEntered(MouseEvent arg0) {
}

@Override
public void mouseExited(MouseEvent arg0) {
}

@Override
public void mousePressed(MouseEvent arg0) {
    repaint();
    c1=arg0.getX();
    c2=arg0.getY();
}

@Override
public void mouseReleased(MouseEvent arg0) {
    repaint();
    if(drag_status==1)
    {
    c3=arg0.getX();
    c4=arg0.getY();
    try
    {
    draggedScreen();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    }
}

@Override
public void mouseDragged(MouseEvent arg0) {
    repaint();
    drag_status=1;
    c3=arg0.getX();
    c4=arg0.getY();
}

@Override
public void mouseMoved(MouseEvent arg0) {

}

public void paint(Graphics g)
{
    super.paint(g);
    int w = c1 - c3;
    int h = c2 - c4;
    w = w * -1;
    h = h * -1;
    if(w<0)
        w = w * -1;
    g.drawRect(c1, c2, w, h);
}
}
You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图