版本1.0:
-
结构:
- 窗体
- 窗体添加按钮
- 监听器
- 动作监听器
- 创建图像处理类对象
- 根据点击的按钮 实现不同的图像处理效果并且绘制出来
- 图像处理类
- 加载图片
- 图像滤镜绘制
我们先对界面进行开发,使用JFrame进行ui界面设计
import javax.swing.*;
import java.awt.*;
public class ImageProUI {
ImageListener il=new ImageListener();
public void showUI(){
JFrame jf=new JFrame();
jf.setTitle("美颜相机v1.0");
jf.setSize(800,800);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
jf.setLayout(new FlowLayout());
//添加按钮
String[] btnStrs={"加载图片","原图","灰度"};
for(int i=0;i<btnStrs.length;i++){
JButton btn=new JButton(btnStrs[i]);
jf.add(btn);
btn.addActionListener(il);
}
jf.setVisible(true);
}
并且对于按钮添加动作监听器
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ImageListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String ac=e.getActionCommand();
System.out.println(ac);
}
}
接着我们开始重新写一个ImageFilter类,对于图像进行处理
我们先去实现一个对于图片进行读取的和转化为每一个坐标所对应的图片的像素的方法
我们来介绍java中自带的几个类的作用
- ImageIO 负责读写图片
- 读: 将一个图片文件对象 读取成一个BufferedImage对象
- 写: 将一个Image对象 保存为一个电脑上的图片文件
- File 类:
- 计算机上 分为文件夹 和 文件 ,在File类中 不管是文件夹还是文件 都是File
- File 类创建的对象只会保存文件 或者文件夹基础信息 ,不包括文件内容基础信息路径 名字 文件格式
- BufferedImage 类: 缓存图像类 :
- 内存中的一张临时图片 ,他提供了很多丰富的功能便于提取设置这张图片的数据
- 获取 宽高
- 根据行列值获取 像素值 /设置像素值
接下来我们来实现这个方法的代码,创建File类来获取文件,将ImageIO读取的文件缓存储存在BufferedImage类中,通过Try—catch进行展开异常处理的扩写,在try方法中获取图片的宽高,创建相对应大小的数组,将read到的图片的像素值存入对应的数组中,并返回数组。
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageFilter {
public int[][] getImagePixArr(String path){
File file=new File(path);
try {
BufferedImage img= ImageIO.read(file);
int w=img.getWidth();
int h=img.getHeight();
int[][] imgArr=new int [w][h];
for(int i=0;i<w;i++){
for (int j=0;j<h;j++){
imgArr[i][j]=img.getRGB(i,j);
}
}
return imgArr;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
实现了图像处理方法,接下来我们来实现图片滤镜方法。
原理不难,其实就是将之前存储像素rgb值的数组进行遍历在坐标上绘制就行,我们来看代码
//图片滤镜方法
//原图
public void drawImage01(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i++) {
for (int j = 0; j < imgArr[i].length; j++) {
int pixNum = imgArr[i][j];
Color color = new Color(pixNum);
g.setColor(color);
g.fillRect(100 + i, 100 + j, 1, 1);
}
}
}
//马赛克
public void drawImage02(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i += 10) {
for (int j = 0; j < imgArr[i].length; j += 10) {
int pixNum = imgArr[i][j];
Color color = new Color(pixNum);
g.setColor(color);
g.fillRect(100 + i, 100 + j, 10, 10);
}
}
}
//灰度
public void drawImage03(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i++) {
for (int j = 0; j < imgArr[i].length; j++) {
int pixNum = imgArr[i][j];
Color color = new Color(pixNum);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int gray = (red + green + blue) / 3;
Color color1 = new Color(gray);
g.setColor(color1);
g.fillRect(100 + i, 100 + j, 1, 1);
}
}
}
//二值化
public void drawImage04(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i++) {
for (int j = 0; j < imgArr[i].length; j++) {
int rgb = imgArr[i][j];
Color color = new Color(rgb);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int gray = (int) (red * 0.30 + green * 0.59 + blue * 0.11);
if (gray < 100) {
g.setColor(Color.BLACK);
} else {
g.setColor(Color.WHITE);
}
g.fillRect(100 + i, 100 + j, 1, 1);
}
}
}
//油画
public void drawImage05(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i += 1) {
for (int j = 0; j < imgArr[i].length; j += 1) {
int rgb = imgArr[i][j];
Color color = new Color(rgb);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
Color color1 = new Color(255 - red, 255 - green, 255 - blue);
g.setColor(color1);
g.fillRect(100 + i, 100 + j, 1, 1);
}
}
}
//反片
public void drawImage06(int[][] imgArr, Graphics g) {
for (int i = 0; i < imgArr.length; i += 1) {
for (int j = 0; j < imgArr[i].length; j += 1) {
int rgb = imgArr[i][j];
Color color = new Color (rgb);
int red = color.getRed ();
int green = color.getGreen ();
int blue = color.getBlue ();
int yred = red + 30;
if(yred > 255){
yred = 255;
}
int ygreen = green + 30;
if(ygreen > 255){
ygreen = 255;
}
Color color1 = new Color (yred, ygreen, 255 - blue);
g.setColor (color1);
g.fillRect (100 + i, 100 + j, 1, 1);
}
}
}
我们接下来将创建的Filter类传给动作监听器
public class ImageListener implements ActionListener {
//图像处理类对象
ImageFilter imgf=new ImageFilter();
并且添加画笔,获取graphics对象即可
public class ImageListener implements ActionListener {
//图像处理类对象
ImageFilter imgf=new ImageFilter();
Graphics g;
int[][] imgArr;
@Override
public void actionPerformed(ActionEvent e) {
String ac=e.getActionCommand();
System.out.println(ac);
if(ac.equals("加载图片")){
imgArr=imgf.getImagePixArr("C:\\Users\\13816\\Desktop\\老大.jpg");
}else if(ac.equals("原图")){
imgf.drawImage01(imgArr,g);
} else if (ac.equals("马赛克")) {
imgf.drawImage02(imgArr,g);
}else if(ac.equals("灰度")){
imgf.drawImage03(imgArr,g);
}else if(ac.equals("二值化")){
imgf.drawImage04(imgArr,g);
}else if(ac.equals("油画")){
imgf.drawImage05(imgArr,g);
}else if(ac.equals("反片")){
imgf.drawImage06(imgArr,g);
}
}
}
public class ImageProUI {
ImageListener il=new ImageListener();
public void showUI(){
JFrame jf=new JFrame();
jf.setTitle("美颜相机v1.0");
jf.setSize(800,800);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
jf.setLayout(new FlowLayout());
//添加按钮
String[] btnStrs={"加载图片","原图","灰度"};
for(int i=0;i<btnStrs.length;i++){
JButton btn=new JButton(btnStrs[i]);
jf.add(btn);
btn.addActionListener(il);
}
jf.setVisible(true);
Graphics g=jf.getGraphics();
il.g=g;
}
public static void main(String[] args) {
ImageProUI imgui=new ImageProUI();
imgui.showUI();
}
}
以上就是初步美颜相机的功能实现