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)
:width
和height
是指定圖像的寬度和高度,主要的作用是放大和縮小圖像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);// 繪制圖像
}
}
}
旋轉圖像
主要用到的是
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就是向正方向平移,平移的長度為shxheight(圖形縱坐標的值,如果是矩形就是乘以矩形的高)
相同的對于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); // 繪制指定大小的圖片
}
}
}
裁剪圖片
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);// 繪制圖像
}
}
}
調整圖片的亮度
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)
是必須有的,這是繪制對緩沖圖像的繪制
總結:
從文件中讀取圖像的方法
- 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,)