package chapter2;java
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.*;
import java.io.File;ide
import java.io.IOException;ui
/**
* Created by LENOVO on 18-1-28.
*/
public class MyFilterUI extends JFrame implements ActionListener{this
private static final long serialVersionUID = 1L;
public static final String GRAY_CMD = "灰度";
public static final String BINARY_CMD = "黑白";
public static final String BLUR_CMD = "模糊";
public static final String ZOOM_CMD = "放縮";
public static final String BROWSER_CMD = "請選擇...";orm
private JButton grayBtn;
private JButton binaryBtn;
private JButton blurBtn;
private JButton zoomBtn;
private JButton browserBtn;
private MyFilters filters;對象
public BufferedImage srcImage;索引
public MyFilterUI(){
this.setTitle("JAVA 2D BufferedImageOp——濾鏡演示");
grayBtn = new JButton(GRAY_CMD);
binaryBtn = new JButton(BINARY_CMD);
blurBtn = new JButton(BLUR_CMD);
zoomBtn = new JButton(ZOOM_CMD);
browserBtn = new JButton(BROWSER_CMD);接口
//添加組件到面板上
JPanel myPanel = new JPanel();
myPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
myPanel.add(grayBtn);
myPanel.add(binaryBtn);
myPanel.add(blurBtn);
myPanel.add(zoomBtn);
myPanel.add(browserBtn);事件
filters = new MyFilters();
getContentPane().setLayout(new BorderLayout());
getContentPane().add(filters,BorderLayout.CENTER);
getContentPane().add(myPanel,BorderLayout.SOUTH);get
//按鈕添加監聽事件
setupActionListener();
}
public void setupActionListener(){
grayBtn.addActionListener(this);
binaryBtn.addActionListener(this);
blurBtn.addActionListener(this);
zoomBtn.addActionListener(this);
browserBtn.addActionListener(this);
}
public void setFileTypeFilter(JFileChooser chooser){
FileNameExtensionFilter filter = new FileNameExtensionFilter("JPG & PNG","jpg","png");
chooser.setFileFilter(filter);
}
@Override
public void actionPerformed(ActionEvent e) {
if(srcImage == null){
JOptionPane.showMessageDialog(this,"請先選擇圖像源文件!");
try{
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);//彈出"打開文件"對話框
File f = chooser.getSelectedFile();//返回所選文件的列表(多個選擇)
srcImage = ImageIO.read(f);
if(f !=null){
filters.setSourceImage(srcImage);
filters.repaint();
}
} catch(IOException e1){
e1.printStackTrace();
}
return ;
}
if(GRAY_CMD.equals(e.getActionCommand())){
//filters.doColorGray(srcImage);
filters.setDestImage( filters.doColorGray(srcImage));
filters.repaint();
}else if(BINARY_CMD.equals(e.getActionCommand())){
//filters.doBinaryImage(srcImage);
filters.setDestImage(filters.doBinaryImage(srcImage));
filters.repaint();
}else if(BLUR_CMD.equals(e.getActionCommand())){
//filters.doBlur(srcImage);
filters.setDestImage(filters.doBlur(srcImage));
filters.repaint();
}else if(ZOOM_CMD.equals(e.getActionCommand())){
//filters.doScale(srcImage,1.5,1.5);
filters.setDestImage(filters.doScale(srcImage,1.5,1.5));
filters.repaint();
}else if(BROWSER_CMD.equals(e.getActionCommand())){
try{
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog(null);//彈出"打開文件"對話框
File f = chooser.getSelectedFile();//返回所選文件的列表(多個選擇)
srcImage = ImageIO.read(f);
if(f != null){
filters.setSourceImage(srcImage);
filters.repaint();
}
} catch(IOException e1){
e1.printStackTrace();
}
}
}
public static void main(String args[]){
MyFilterUI ui = new MyFilterUI();
ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ui.setPreferredSize(new Dimension(800,600));
ui.pack();
ui.setVisible(true);
}
public static class MyFilters extends JPanel{
public BufferedImage sourceImage;
public BufferedImage destImage;
public BufferedImage getSourceImage() {
return sourceImage;
}
public void setSourceImage(BufferedImage sourceImage) {
this.sourceImage = sourceImage;
}
public BufferedImage getDestImage() {
return destImage;
}
public void setDestImage(BufferedImage destImage) {
this.destImage = destImage;
}
public MyFilters(){
// super();
}
public void paintComponent(Graphics g){
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.clearRect(0,0,this.getWidth(),this.getHeight());
if(sourceImage != null){
g2d.drawImage(sourceImage,0,0, sourceImage.getWidth(), sourceImage.getHeight(),null);
if(destImage != null){
g2d.drawImage(destImage,sourceImage.getWidth()+10,0,destImage.getWidth(),
destImage.getHeight(),null);
}
}
//g2d.drawImage(srcImage,0,0, srcImage.getWidth(), srcImage.getHeight(),this);
}
/*實現灰度化
ColorConvertOp主要用於實現各類色彩空間的轉換,實現灰度功能時,只需在實例化
ColorConvertOp時指定色彩空間爲ColorSpace.CS_GRAY,而後調用它的filter方法返回圖像便可。
*/
public BufferedImage doColorGray(BufferedImage bi){
ColorConvertOp filterObj = new ColorConvertOp(
ColorSpace.getInstance(ColorSpace.CS_GRAY),null
);
return filterObj.filter(bi,null);
}
/*實現黑白功能
* LookupOp在實例化時須要傳入LookupTable實例,當前實現LookupTable接口的兩個實現類爲
* ByteLookupTable和ShortLookupTable
* 1)首先將圖像灰度化
* 2)針對灰度圖像在LookupTable中根據像素值進行索引查找,以便設置新的像素值,從而獲得黑白兩色圖像
*/
public BufferedImage doBinaryImage(BufferedImage bi){
bi = doColorGray(bi);//圖像灰度化
byte[] threshold = new byte[256];
for (int i = 0; i<256;i++){
threshold[i] = (byte) ((i<128)? 0:255);
}
BufferedImageOp thresholdOp = new LookupOp(new ByteLookupTable(0,threshold),null);
return thresholdOp.filter(bi,null);
}
/*實現模糊功能
* ConvloveOp是實現模板卷積功能操做的類,經過簡單設置卷積核/卷積模板就能夠實現圖像模糊功能
* 多數狀況下圖像使用TYPE_3BYTE_BGR存儲方式,而BufferedImageOp實現的濾鏡不支持操做該存儲方式的BufferedImage對像
* 解決方法是首先經過ColorConvertOp把圖像從類型TYPE_3BYTE_BGR轉換爲TYPE_INT_RGB的BufferedImage對象
*/
public BufferedImage convertType(BufferedImage src,int type){
ColorConvertOp cco = new ColorConvertOp(null);
BufferedImage dest = new BufferedImage(src.getWidth(),src.getHeight(),type);
cco.filter(src,dest);
return dest;
}
public BufferedImage doBlur(BufferedImage bi){
if(bi.getType() == BufferedImage.TYPE_3BYTE_BGR){
bi = convertType(bi,BufferedImage.TYPE_INT_RGB);
}
float ninth = 1.0f/9.0f;
float[] blurKernal = {
ninth,ninth,ninth,
ninth,ninth,ninth,
ninth,ninth,ninth
};
BufferedImageOp blurFilter = new ConvolveOp(new Kernel(3,3,blurKernal));
return blurFilter.filter(bi,null);
}
/*實現zoom in/out的功能
* AffineTransformOp支持的操做包括圖像的錯切、旋轉、放縮、平移
* 首先要經過 AffineTransform.getScaleInstance來獲取Scale實例,而後做爲參數初始化AffineTransformOp實例
*/
public BufferedImage doScale(BufferedImage bi,double sx,double sy){
AffineTransformOp atFilter = new AffineTransformOp(AffineTransform.getScaleInstance(sx,sy),AffineTransformOp.TYPE_BILINEAR);
//計算放縮後圖像的寬與高
int nw = (int) (bi.getWidth()*sx);
int nh = (int) (bi.getHeight()*sy);
BufferedImage result = new BufferedImage(nw,nh,BufferedImage.TYPE_3BYTE_BGR);
return atFilter.filter(bi,result);
}
}
}