文章目录
画图板UI
主方法
设置画图板
添加按钮
重写paint方法
拖动的时候图像不消失
鼠标监听器
初始化画笔及创建储存图像数组
重写actionPerformed方法
使用图片原理与处理实现滤镜效果
基础知识
每一张图片都是由像素点组成的,每一个像素点都有其对应的RGB值,我们通过获取图片的RGB值并进行修改达到各种滤镜效果。
设置开始绘画的坐标:
将照片转化为二维数组
将照片转成二维数组,之后遍历数组,将照片绘制出来。
模拟红外线
int newred=red+125;
if(newred>255) {
newred=newred-255;
}
Color scolor =new Color(newred,0,0);
原图
马赛克
反片
灰度
二值化
去除背景
图像合成
轮廓提取
清除
浮雕
油画
怀旧
图像融合
打开照片
撤回
刷新及保存图片
视频处理
原理
视频组成:多张图片轮播 1s 24张
FPS: 24帧 帧率越高代表视频越细致流畅
屏幕刷新率: 60Hz
视频图像获取:
http://webcam-capture.sarxos.pl/
- Eclipse :
- *项目:
- 1: 右键项目名 Build Path - Config BuildPath - Lib - add Jars 选中
- IDEA :
- 1:右键项目名 Module Setting
- 2:找到 lib -> +号 Java 选中jar包
package com.lqj220309;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.github.sarxos.webcam.Webcam;
public class WebcamTest extends JFrame {
BufferedImage image;
Graphics g;
public static void main(String[] args) {
new WebcamTest().initUI();
}
public void initUI() {
setTitle("webcamtset");
setSize(800,800);
setDefaultCloseOperation(3);
setLayout(null);
JButton btn=new JButton("拍照");
btn.setBounds(400, 200, 80, 35);
btn.setBackground(Color.white);
add(btn);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
g.drawImage(image, 450, 50, null);
try {
long time =System.currentTimeMillis();
ImageIO.write(image, "JPG", new File("./test"+time+".jpg"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
setVisible(true);
g=getGraphics();
Webcam webcam =Webcam.getDefault();
List<Webcam> webcams=Webcam.getWebcams();
System.out.print("摄像头数量"+webcams.size());
//![请添加图片描述](https://img-blog.csdnimg.cn/01eaed72b9024b67abdf343813c2f215.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASOOAgWNhwqU=,size_20,color_FFFFFF,t_70,g_se,x_16)
Webcam webcam =webcams.get(1);
webcam.open();
while (true) {
image =webcam.getImage();
System.out.print(image);
Graphics bg =image.getGraphics();
//将图像改成马赛克
for(int i=0;i<image.getWidth()-10;i+=10) {
for(int j=0;j<image.getHeight()-10;j+=10) {
int rgb =image.getRGB(i,j);
bg.setColor(new Color(rgb));
bg.fillOval(i, j, 10, 10);
}
}
g.drawImage(image, 15, 50, null);
System.out.print(webcam.getFPS());
g.drawString(webcam.getFPS()+"", 15, 50);
}
}
}
package com.lqj220309;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;
import com.github.sarxos.webcam.Webcam;
public class UI extends JFrame{
UI(){
setTitle("视频播放");
setSize(800,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public void playvideo(Graphics g,Webcam webcam) {
Random random=new Random();
while(true) {
long start =System.currentTimeMillis();
int rgb=random.nextInt(Integer.MAX_VALUE);
//创建图片
BufferedImage img= webcam.getImage();
//设计颜色
for(int i=0;i<300;i++) {
for(int j=0;j<300;j++) {
img.setRGB(i, j, img.getRGB(i, j));
}
}
//绘制图像
g.drawImage(img, 100, 100, null);
//休眠休眠500ms帧率大概为一秒钟一张
try {
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
long end =System.currentTimeMillis();
System.out.print("\nFPS:"+1000/(end-start));
}
}
public static void main(String[] args) {
UI ui =new UI();
Webcam webcam = Webcam.getWebcams().get (1);
ui.playvideo(ui.getGraphics(),webcam);
}
}
可以获取摄像头
可以实现拍照功能
可以选择对应的项进行处理
视频播放
public class PlayVideo{
// 控制循环中绘制不同类型特效的字符串
String btnstr="";
// 图像处理类
ImageEff imageEff = new ImageEff ();
/**
* 播放视频
* @param webcam
* @param g
*/
public void runVideo(Webcam webcam, Graphics g) {
// 开启绘制视频的死循环
while(true) {
// 获取图片
BufferedImage img = webcam.getImage ();
// 判断如何处理图片 并调用图片处理类来绘制
if(btnstr.equals("原视频")) {
g.drawImage( img, 100,100, null);
}
if(btnstr.equals("马赛克")) {
//传入缓冲图像对象,获取二维图像数组
int[][] imagePixArray= imageEff.getImagePixArray(img);
//绘制马赛克
imageEff.drawImage_02(imagePixArray, g);
}
if(btnstr.equals("灰度")) {
// webcam.close();
}
//绘制
}
}}
图像处理
public class ImageEff {
final int X=100;
final int Y=100;
//获取图像数组
int[][] getImagePixArray(BufferedImage buffimg){
int w=buffimg.getWidth();
int h =buffimg.getHeight();
int[][] imagearr=new int[w][h];
for(int i=0;i<w;i++) {
for(int j=0;j<h;j++) {
imagearr[i][j]=buffimg.getRGB(i, j);
}
}
return imagearr;
}
//原图 返回值为bufferedimage保存图片
BufferedImage drawImage_01(int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length;i++) {
for(int j=0;j<imagearr[i].length;j++) {
int rgb=imagearr[i][j];
//通过设置bufferedimage的RBG值
bufferedimage.setRGB(i, j, rgb);
/*
一个一个的画导致画的比较慢
Color color=new Color(rgb);
g.setColor(color);
g.fillRect(X+i, Y+j, 1, 1);
*/
}
}
//bufferedimage都存入rbg的值后可一次性
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//马赛克
BufferedImage drawImage_02 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
//通过获取缓冲图的Graphices,在缓冲图上绘制
Graphics buffimagra=bufferedimage.getGraphics();
for(int i=0;i<imagearr.length-10;i+=10) {
for(int j=0;j<imagearr[i].length-10;j+=10) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
//用缓冲图的画笔绘制到缓冲图中
buffimagra.setColor(color);
buffimagra.fillRect(i, j, 10, 10);
//g.fillOval(X+i, Y+j, 10, 10);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//反片
BufferedImage drawImage_03 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length;i++) {
for(int j=0;j<imagearr[i].length;j++) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int blue=color.getBlue();
int green=color.getGreen();
Color fanpian =new Color(255-red,255-green,255-blue);
bufferedimage.setRGB(i, j,fanpian.getRGB());
// g.setColor(fanpian);
// g.fillRect(X+i, Y+j, 1, 1);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//灰度
BufferedImage drawImage_04 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length;i++) {
for(int j=0;j<imagearr[i].length;j++) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int blue=color.getBlue();
int green=color.getGreen();
//要记得转成int类型
int gray=(int)(red*0.41+blue*0.36+green*0.23);
Color huidu =new Color(gray,gray,gray);
bufferedimage.setRGB(i, j,huidu.getRGB());
//g.setColor(huidu);
//g.fillRect(X+i, Y+j, 1, 1);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//二值化
BufferedImage drawImage_05 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length;i++) {
for(int j=0;j<imagearr[i].length;j++) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int blue=color.getBlue();
int green=color.getGreen();
int gray=(red+blue+green)/3;
//要在gray得基础上二值化
if(gray<50) {
bufferedimage.setRGB(i, j,Color.BLACK.getRGB());
//g.setColor(Color.BLACK);
}else {
bufferedimage.setRGB(i, j,Color.WHITE.getRGB());
//g.setColor(Color.WHITE);
}
//g.fillRect(X+i, Y+j, 1, 1);
}
g.drawImage(bufferedimage, X, Y, null);
}
return bufferedimage;
}
//去除背景
BufferedImage drawImage_06 (int[][] imagearr,Graphics g) {
ImageEff imageeff=new ImageEff();
imageeff.drawImage_09(imagearr, g);
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0; i<imagearr.length; i++) {
for(int j=0; j<imagearr[0].length; j++) {
int rgb =imagearr[i][j];
Color color = new Color(rgb);
//去背景,只画高于某一值的颜色,有不同去背景效果
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
if(green<225) {
Color nc =new Color(red, green,blue);
bufferedimage.setRGB(i, j,nc.getRGB());
}
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//图像合成
BufferedImage drawImage_07 (int[][] imagearr1,int[][] imagearr2,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr1.length,imagearr1[0].length,BufferedImage.TYPE_INT_ARGB);
//图像缩小
int LM=imagearr2.length/5;
int HM=imagearr2[0].length/5;
int[][] suoxiao=new int [LM] [HM];
int q=0,w=0;
for(int a=0;a<imagearr2.length;a+=5) {
for(int b=0;b<imagearr2[a].length;b+=5) {
int rgb=imagearr2[a][b];
suoxiao[q][w]=rgb;
q=a/5;
w=b/5;
}
}
int a=0,b=0;
for(int i=0;i<imagearr1.length;i++) {
for(int j=0;j<imagearr1[i].length;j++) {
if(i>=imagearr1.length-LM && j>=imagearr1[i].length-HM) {
int rgb2=suoxiao[a][b];
Color color=new Color(rgb2);
//去掉白边
if(rgb2==Color.white.getRGB()) {
int rgb1=imagearr1[i][j];
color=new Color(rgb1);
}
bufferedimage.setRGB(i, j,color.getRGB());
a=i-(imagearr1.length-LM);
b=j-(imagearr1[i].length-HM);
}else {
int rgb1=imagearr1[i][j];
Color color=new Color(rgb1);
bufferedimage.setRGB(i, j,color.getRGB());
}
//g.setColor(color);
//g.fillRect(X+i, Y+j, 1, 1);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//轮廓提取同样要在灰度基础上
BufferedImage drawImage_08 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length-2;i++) {
for(int j=0;j<imagearr[i].length-2;j++) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
int red=color.getRed();
int blue=color.getBlue();
int green=color.getGreen();
//要记得转成int类型
int gray=(int)(red*0.41+blue*0.36+green*0.23);
//要对比
int nrgb=imagearr[i+2][j+2];
Color ncolor=new Color(nrgb);
int nred=ncolor.getRed();
int nblue=ncolor.getBlue();
int ngreen=ncolor.getGreen();
int ngray=(int)(nred*0.41+nblue*0.36+ngreen*0.23);
if(Math.abs(gray-ngray)>15) {
bufferedimage.setRGB(i, j,Color.BLACK.getRGB());
//g.setColor(Color.BLACK);
}else {
bufferedimage.setRGB(i, j,Color.white.getRGB());
//g.setColor(Color.WHITE);
}
//g.fillRect(X+i, Y+j, 1, 1);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//清除
BufferedImage drawImage_09 (int[][] imagearr,Graphics g) {
// BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
// for(int i=0;i<imagearr.length;i++) {
// for(int j=0;j<imagearr[i].length;j++) {
// Color qingping=new Color(238,238,238);
// bufferedimage.setRGB(i, j, qingping.getRGB());
// }
// }
// g.drawImage(bufferedimage, X, Y, null);
// return bufferedimage;
BufferedImage bufferedimage =new BufferedImage(700,700,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<700;i++) {
for(int j=0;j<700;j++) {
Color qingping=new Color(238,238,238);
bufferedimage.setRGB(i, j, qingping.getRGB());
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//浮雕
BufferedImage drawImage_10 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length-1;i++) {
for(int j=0;j<imagearr[i].length-1;j++) {
int rgb1=imagearr[i][j];
int rgb2=imagearr[i+1][j+1];
Color color1=new Color(rgb1);
Color color2=new Color(rgb2);
int red=128+color1.getRed()-color2.getRed();
int blue=128+color1.getBlue()-color2.getBlue();
int green=128+color1.getGreen()-color2.getGreen();
if(red>255) {
red=255;
}
if(red<0) {
red=0;
}
if(blue>255) {
blue=255;
}
if(blue<0) {
blue=0;
}
if(green>255) {
green=255;
}
if(green<0) {
green=0;
}
Color fudiao =new Color(red,green,blue);
bufferedimage.setRGB(i, j,fudiao.getRGB());
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//油画
BufferedImage drawImage_11 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
Graphics buffimagra=bufferedimage.getGraphics();
for(int i=0;i<imagearr.length;i+=4) {
for(int j=0;j<imagearr[i].length;j+=4) {
int rgb=imagearr[i][j];
Color color=new Color(rgb);
buffimagra.setColor(color);
Random ran = new Random();
int r = ran.nextInt(20)+5;
buffimagra.fillOval(i, j, r, r);
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//怀旧
BufferedImage drawImage_12 (int[][] imagearr,Graphics g) {
BufferedImage bufferedimage =new BufferedImage(imagearr.length,imagearr[0].length,BufferedImage.TYPE_INT_ARGB);
for(int i=0;i<imagearr.length;i++) {
for(int j=0;j<imagearr[i].length;j++) {
int rgb0=imagearr[i][j];
Color color7=new Color(rgb0);
int[] rgb=new int[3];
rgb[0] = (int) (0.393*color7.getRed()+0.769*color7.getGreen()+0.189*color7.getBlue());
rgb[1] = (int) (0.349*color7.getRed()+0.686*color7.getGreen()+0.168*color7.getBlue());
rgb[2] = (int) (0.272*color7.getRed()+0.534*color7.getGreen()+0.131*color7.getBlue());
for(int m=0;m<3;m++) {
if(rgb[m]<0)
rgb[m]=0;
else if(rgb[m]>255)
rgb[m]=255;
}
Color huaijiu = new Color(rgb[0],rgb[1],rgb[2]);
bufferedimage.setRGB(i, j,huaijiu.getRGB());
}
}
g.drawImage(bufferedimage, X, Y, null);
return bufferedimage;
}
//图像融合
BufferedImage drawImage_13 (int[][] imagearr1,int[][] imagearr2,Graphics g) {
int w = 0;
int h = 0;
if(imagearr1.length < imagearr2.length){
w = imagearr2.length;
} else{
w = imagearr1.length;
}
if(imagearr1[0].length < imagearr2[0].length){
h = imagearr2[0].length;
} else{
h = imagearr1[0].length;
}
// 缓冲图片对象
BufferedImage img = new BufferedImage
(w, h, BufferedImage.TYPE_INT_ARGB);
// 如何不绘制特殊形状 可以考虑直接设置RGB值
for(int i = 0; i < w; i++){
for(int j = 0; j < h; j++){
int rgb = 0;
int rgb2 = 0;
if(i < imagearr1.length && j < imagearr1[0].length){
rgb = imagearr1[i][j];
}
if(i < imagearr2.length && j < imagearr2[0].length){
rgb2 =imagearr2[i][j];
}
Color color1 = new Color (rgb);
Color color2 = new Color (rgb2);
// 创建一个融合颜色
int red = color1.getRed () / 2 + color2.getRed () / 2;
int green = color1.getGreen () / 2 + color2.getGreen () / 2;
int blue = color1.getBlue () / 2 + color2.getBlue () / 2;
Color newColor = new Color (red, green, blue);
img.setRGB (i, j, newColor.getRGB ());
}
}
// 一次性绘制这张照片
g.drawImage (img, X, Y, null);
// 返回img对象
return img;
}
}
视频UI和监听器
public class VideoListener implements ActionListener {
PlayVideo playVideo;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String btnstr =e.getActionCommand();
//点击按钮之后,修改死循环中的判断所用到的 变量的值
playVideo.btnstr=btnstr;
// if(btnstr.equals("原视频")) {
// palyVideo.
// }
// if(btnstr.equals("马赛克")) {
//
// }
// System.out.print("点击了"+btnstr);
}
}
public class VideoListener implements ActionListener {
PlayVideo playVideo;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String btnstr =e.getActionCommand();
//点击按钮之后,修改死循环中的判断所用到的 变量的值
playVideo.btnstr=btnstr;
// if(btnstr.equals("原视频")) {
// palyVideo.
// }
// if(btnstr.equals("马赛克")) {
//
// }
// System.out.print("点击了"+btnstr);
}
}