新建一个滤镜操作的类ImageFilter,已经实现了原图,灰度图,二值化,马赛克效果。
import java.awt.*;
import java.awt.image.BufferedImage;
public class ImageFilter {
public BufferedImage drawImage(Graphics g, BufferedImage image) {
g.drawImage(image, 0, 0, null);
return image;
}
public BufferedImage grayImageFilter(Graphics g, BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = image.getRGB(i, j);
int red = (rgb >> 16) & 0xff;
int green = (rgb >> 8) & 0xff;
int blue = rgb & 0xff;
int gray = (int) (0.3 * red + 0.35 * green + 0.35 * blue);
rgb = (rgb & 0xff000000) | (gray << 16) | (gray << 8) | gray;
image.setRGB(i, j, rgb);
}
}
g.drawImage(image, 0, 0, null);
return image;
}
public BufferedImage binaryImageFilter(Graphics g, BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = image.getRGB(i, j);
int red = (rgb >> 16) & 0xff;
int green = (rgb >> 8) & 0xff;
int blue = rgb & 0xff;
int gray = (int) (0.3 * red + 0.35 * green + 0.35 * blue);
if (gray > 70) {
gray = 255;
} else {
gray = 0;
}
rgb = (rgb & 0xff000000) | (gray << 16) | (gray << 8) | gray;
image.setRGB(i, j, rgb);
}
}
g.drawImage(image, 0, 0, null);
return image;
}
public BufferedImage mosaicImageFilter(Graphics g, BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage image0 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i+=10) {
for (int j = 0; j < height; j+=10) {
int rgb = image.getRGB(i, j);
for (int k = 0; k < 10; k++) {
for (int l = 0; l < 10; l++) {
image0.setRGB(i+k, j+l, rgb);
}
}
}
}
g.drawImage(image0, 0, 0, null);
return image0;
}
}
在线程RunVideoAble中的run()函数中加入判断选择滤镜效果。
import com.github.sarxos.webcam.Webcam;
import java.awt.*;
import java.awt.image.BufferedImage;
public class RunVideoAble implements Runnable{
Webcam webcam = Webcam.getDefault();
boolean flag = false;
Graphics g = null;
BufferedImage image = null;
ImageFilter imageFilter = new ImageFilter();
String videoOp = "原图";
public RunVideoAble(Webcam webcam, Graphics g) {
this.webcam = webcam;
this.g = g;
}
public BufferedImage getImage() {
return image;
}
public void open() {
flag = true;
webcam.open();
}
public void close() {
flag = false;
webcam.close();
}
public void setVideoOp(String videoOp) {
this.videoOp = videoOp;
}
@Override
public void run() {
while (flag) {
image = webcam.getImage();
if (videoOp.equals("原图")) {
g.drawImage(image, 0, 0, null);
} else if (videoOp.equals("灰度图")) {
image = imageFilter.grayImageFilter(g, image);
} else if (videoOp.equals("二值化")) {
image = imageFilter.binaryImageFilter(g, image);
} else if (videoOp.equals("马赛克")) {
image = imageFilter.mosaicImageFilter(g, image);
}
}
}
}
滤镜的效果依旧通过监听器(VCListener)来选择。修改RunVideoAble中的videoOp控制滤镜。
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class VCListener implements ActionListener {
Graphics g = null;
boolean flag = false;
RunVideoAble rvt;
Webcam webcam = Webcam.getDefault();
public void setG(Graphics g) {
this.g = g;
}
@Override
public void actionPerformed(ActionEvent e) {
String ac = e.getActionCommand();
JButton btn = (JButton)e.getSource();
String str = btn.getText();
// webcam.setViewSize(WebcamResolution.VGA.getSize());
if (ac.equals("camOp")) {
if (str.equals("启动")) {
rvt = new RunVideoAble(webcam, g);
rvt.open();
Thread t = new Thread(rvt);
t.start();
} else if (str.equals("关闭")) {
rvt.close();
webcam.close();
} else if (str.equals("拍照")) {
BufferedImage image = rvt.getImage();
// g.drawImage(image, 500, 500, null);
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " +
chooser.getSelectedFile().getName());
try {
ImageIO.write(image, "png", chooser.getSelectedFile());
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
} else if (ac.equals("videoOp")) {
rvt.setVideoOp(str);
}
}
}
按钮处 setActionCommand() 用于监听器中判断是 camOp 还是 videoOp 。
import javax.swing.*;
import java.awt.*;
public class VideoCapture extends JFrame {
String[] camstrs = {"启动", "关闭", "拍照"};
String[] filterstrs = {"原图", "灰度图", "二值化", "马赛克"};
VCListener vcl = new VCListener();
public void initUI() {
setTitle("VideoCapture");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 500);
setLocation(360, 210);
JPanel vpanel = new JPanel();
JPanel bpanel = new JPanel();
vpanel.setBackground(Color.BLACK);
bpanel.setBackground(Color.LIGHT_GRAY);
add(vpanel, BorderLayout.CENTER);
add(bpanel, BorderLayout.SOUTH);
for (String str: camstrs) {
JButton btn = new JButton(str);
btn.setPreferredSize(new Dimension(80, 50));
btn.setActionCommand("camOp");
btn.addActionListener(vcl);
bpanel.add(btn);
}
for (String str: filterstrs) {
JButton btn = new JButton(str);
btn.setPreferredSize(new Dimension(80, 50));
btn.setActionCommand("videoOp");
btn.addActionListener(vcl);
bpanel.add(btn);
}
setVisible(true);
vcl.setG(vpanel.getGraphics());
}
public static void main(String[] args) {
new VideoCapture().initUI();
}
}
通过运行程序,并将加上滤镜后的效果成功保存到计算机中。
1. 原图 2. 灰度图
3. 二值化 4. 马赛克