综述:
对于一个简单的Java图像处理程序来说,我们应该坚持以成果为导向的编程思想,那么我们以美颜相机举例,来分析一个程序都需要什么。
1、UI界面
2、监听器
3、工具类面板
接下来为大家详细解释各部分的作用以及含义 > > >
<UI界面> : 大部分需要交互的程序都需要UI界面来实现交流互动。
<监听器> :人们在UI中的操作需要监听器来捕捉和执行相应的命令。
<工具类面板> :将执行命令的方法单独封装成工具类,供监听器调用。
1. UI界面
实现UI界面,需要一个窗体,并在其中添加各种各样的功能区域、按钮。
美颜相机中需要显示和绘制图像的区域、各种特效工具按钮的区域。(可以再细分)
并且要给鼠标加上监听器以知道人们操作了什么。
我们用美颜相机项目的代码详细说明。
【PS:窗体的创建方法有两类,分别为
1、
public class ImageProUI extends JFrame {}
2、
import javax.swing.*;
import java.awt.*;
public class Test{
public void ShowUI(){
JFrame jf = new JFrame();//设置窗体的渐入
以上】
PPS:图像结构:像素点 数码图像
图像处理工具的本质是处理像素点,而像素点的本质就是一种颜色:
数码三原色: Red Green Blue
取值范围:(0-255)256阶
使用数字表示每种颜色的值(深浅程度)
黑色:(0,0,0)
白色:(255 255 255)
红色:(255,0,0)
灰色: R=G=B
图像处理知识:
1、图像处理的本质是在修改图片的像素值,而每一个像素点的本质是RGB三原色组成
2、图片的本质是一个int型的二维数组,所以图像 = int[ ] [ ]
3、Color类可以实现数字颜色的转化。色即是数,数即是色。
获取RGB三原色的分量值:
1、取出所有的像素值,把像素值转为Color对象,通过调用Color对象的getRed,getGreen,getBlue方法获取
//取出所有的像素值
int pixel = pixelArr[i][j];
//将像素值转化为1Color对象
Color color = new color(pixel);
//获取rgb平均值
int red = color.getRed();
int blue = color.getBlue();
int green = color.getGreen();
2、通过将像素值右移相应的位数,再进行与操作
//取出所有像素值
int pixel = pixelArr[i][j];
//通过右移获取pixel像素里的三原色
对于UI界面的设计,如下代码所示:
代码实现
1、想要写一个界面(具体参照之前)
package testll;
import javax.swing.JFrame;
import java.awt.*;
public class ImagePad extends JFrame{
public static void main(String[] args){
ImagePad imgpad = new ImagePad ();
imgpad.initUI ();
}
public void initUI(){
this.setTitle ("图像处理");
this.setSize (800, 800);
this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
this.setVisible (true);
}
@Override
public void paint(Graphics g){
super.paint (g);
// 此处用来绘制 绘制的代码都写在这里就可以
}
}
窗体
界面的效果:
2、我们尝试画一个200*200的图像,像素点的值我们让它随机,并且让它画出彩色的图形。
代码实现如下:
package 马赛克图;
import javax.swing.JFrame;
import java.awt.*;
import java.util.Random;
public class 冲冲冲 extends JFrame{
public void showUI(){
setTitle ("马赛克图");
setSize (1200, 700);
setDefaultCloseOperation (EXIT_ON_CLOSE);
setVisible (true);
}
@Override//这个可以用灯泡召唤出来@
public void paint(Graphics g){
super.paint (g);//生成画笔
// g
// 随机生成像素
Random random = new Random ();
int[][] pixArray = new int[500][500];
// 生成了一个像素值矩阵
for(int i = 0; i < 500; i++){
for(int j = 0; j < 500; j++){
int red = random.nextInt (256);
int green = random.nextInt (256);
int blue = random.nextInt (256);
int rgb = (red << 16) + (green << 8) + blue;
pixArray[i][j] = rgb;
}
}
// 绘制
for(int i = 0; i < 500; i += 10){
for(int j = 0; j < 500; j += 10){
int rgb = pixArray[i][j];
int red = (rgb >> 16) & 255;
int green = (rgb >> 8) & 255;
int blue = (rgb >> 0) & 255;
Color color = new Color (red, green, blue);
g.setColor (color);
g.fillRect (20 + i, 100 + j, 10, 10);
}
}
}
public static void main(String[] args){
冲冲冲 ip = new 冲冲冲 ();
ip.showUI ();
}
}
灰度效果:
// 绘制
for(int i = 0; i < 500; i+=10){
for(int j = 0; j < 500; j+=10){
int rgb = pixArray[i][j];
int red = (rgb >> 16) & 255;
int green = (rgb >> 8) & 255;
int blue = (rgb >> 0) & 255;
int gray = (red+green+blue)/3;
// red == green == blue 就是灰色
Color color = new Color (gray, gray, gray);
g.setColor (color);
g.fillRect (550 + i, 100 + j, 10, 10);
}
}
显然,只随机生成是不够的,我们要编写一个能直接根据本机路径获取图片的函数并将图片显示在界面上。
int [][] imgarr = getPixelArray("C:\\Users\\Mycomputer\\Desktop\\蓝杰\\wxy.jpg");
int w = imgarr.length;
int h = imgarr[0].length;
for(int i = 0 ; i < w ; i++){
for(int j = 0 ; j < h ; j++){
int rgb = imgarr[i][j];
Color color = new Color(rgb);
g.setColor(color);
g.fillRect(50+i,50+j,1,1);
}
}
}
public int[][] getPixelArray(String imgPath){
File file = new File(imgPath);
BufferedImage buffimg = null;
try{
buffimg = ImageIO.read(file);
}catch(IOException e){
e.printStackTrace();
}
int w = buffimg.getWidth();
int h = buffimg.getHeight();
int[][] imgarr = new int[w][h];
for(int i = 0 ; i < w ; i++){
for(int j = 0 ; j < h ; j++){
imgarr[i][j] = buffimg.getRGB(i,j);
}
}
return imgarr;
-
3、将图像转换为二维数组的方法
-
public int[][] getPixelArray(String imgPath){ // 根据图片地址 生成一个file对象 ,file 对象读取 File file = new File (imgPath); // 声明一个BUfferedImage变量名 BufferedImage buffimg = null; // 使用图片IO读取文件 try { buffimg = ImageIO.read (file); } catch (IOException e) { e.printStackTrace (); } // 获取宽度 高度 int w = buffimg.getWidth (); int h = buffimg.getHeight (); // 定义一个与图片像素宽高一致的二维数组 int[][] imgarr = new int[w][h]; // 遍历BufferedImage 获取RGB值 存储 数组中 for(int i = 0; i < w; i++){ for(int j = 0; j < h; j++){ imgarr[i][j] = buffimg.getRGB (i, j); } } // 将存好像素值的数组 返回 return imgarr; }
4、绘制图片的方法(重点对象)
-
public void paint(Graphics g) { super.paint (g); //申请一个二维数组,用来储存图片信息 int[][] imgarr = getPixelArray ("此处填写文件路径"); //示例: 路径\\文件名.后缀 // ("C:\\Users\\Desktop\\picture\\picture2.jpeg"); int w = imgarr.length; int h = imgarr[0].length; /** 第一种方法:绘制原图绘制原图 **/ public void drawImage_01(int[][] imgarr,Graphics g) { for(int i=0;i<imgarr.length;i++) { for(int j=0;j<imgarr.length;j++) { int rgb = imgarr[i][j]; Color color =new Color(rgb); g.setColor(color); g.fillRect(X+i,Y+j,1,1); } } } /** 第一种方法:绘制原图绘制原图 **/ }
接下来可以换其他的方法
第二种:灰度图
-
for(int i = 0; i < w; i++){ for(int j = 0; j < h; j++){ int rgb = imgarr[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; Color ncolor = new Color(gray,gray,gray); g.setColor(ncolor); g.fillRect(100+i,100+j,1,1); } }
第三种:二值化图
-
for(int i = 0; i < w; i++){ for(int j = 0; j < h; j++){ int rgb = imgarr[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; Color ncolor = new Color(gray,gray,gray); // 二值化 在灰度的基础上 通过灰度值来判断 if(gray < 80){ g.setColor (Color.BLACK); } else{ g.setColor (Color.WHITE); } g.fillRect (100 + i, 100 + j, 1, 1); } } }
反转颜色
//下接绘制的代码
int [][] imgarr = getPixelArray("C:\\Users\\LENOVO\\Desktop\\蓝杰\\wxy.jpg");
int w = imgarr.length;
int h = imgarr[0].length;
for(int i = 0 ; i < w ; i++){
for(int j = 0 ; j < h ; j++){
int rgb = imgarr[i][j];
Color color = new Color(rgb);
// 获取RGB三原色
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
//灰度
int gray = (red + green + blue) / 3;
// red=green=blue 则照片颜色只剩下灰阶色彩
Color nColor = new Color (255-red, 255-green, 255-blue);//0-255
g.setColor(nColor);
g.fillRect(50+i,50+j,1,1);
}
}
PS:
冷色调Color nColor = new Color (red/2, green/2, blue);//0-255
暖色调Color nColor = new Color (red, green/2, blue/2);//0-255
-
小总结
-
1、主函数部分,创建一个类对象,用类对象创建成员方法
//主函数部分
public static void main(String[] args) {
ImagePad imgPad = new ImagePad();
imgPad.intUI();
}
2、生成函数界面部分,直接用this来调用方法设置标题,设置大小,设置退出方法,设置可视化;
public void initUI(){
/**
* 因为ImagePad为继承类,所以可以用this来调用setTitle等JFrame中的方法;
*/
//设置标题
this.setTitle ("图像处理");
this.setSize (800, 800);
this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
//在可视化之后获取
this.setVisible (true);
3、将图像转换为二维数组的方法部分
public int[][] getPixelArray(String imgPath){
// 根据图片地址 生成一个file对象 ,file 对象读取
File file = new File (imgPath);
// 声明一个BUfferedImage变量名
BufferedImage buffimg = null;
// 使用图片IO读取文件
try { buffimg = ImageIO.read (file); }
catch (IOException e) { e.printStackTrace (); }
// 获取宽度 高度
int w = buffimg.getWidth ();
int h = buffimg.getHeight ();
// 定义一个与图片像素宽高一致的二维数组
int[][] imgarr = new int[w][h];
// 遍历BufferedImage 获取RGB值 存储 数组中
for(int i = 0; i < w; i++){
for(int j = 0; j < h; j++){
imgarr[i][j] = buffimg.getRGB (i, j);
}
}
// 将存好像素值的数组 返回
return imgarr;
4、
public void paint(Graphics g)
{
super.paint (g);
//申请一个二维数组,用来储存图片信息
int[][] imgarr = getPixelArray ("此处填写文件路径");
//示例: 路径\\文件名.后缀
// ("C:\\Users\\Desktop\\picture\\picture2.jpeg");
int w = imgarr.length;
int h = imgarr[0].length;
/** 第一种方法:绘制原图绘制原图 **/
public void drawImage_01(int[][] imgarr,Graphics g) {
for(int i=0;i<imgarr.length;i++) {
for(int j=0;j<imgarr.length;j++) {
int rgb = imgarr[i][j];
Color color =new Color(rgb);
g.setColor(color);
g.fillRect(X+i,Y+j,1,1);
}
}
}
总结:
在界面上显示出图片,原理为导入图片文件,获取图片的高和宽,将每一个像素点存在数组中南,将图片文件转换为二维数组,最后利用绘制图片的方法将图片绘制出。