图像处理美颜相机——基本功能实现
项目完整知识点(这里只实现了基本功能)
- 基本功能
- 图像原理 像素 矩阵 二进制位运算 十进制 十六进制
- 基本的文件操作 读取照片 保存照片
- 界面开发 – 优化 自适应操作 刷新 图层、监听器
- 图像算法 RGB 灰度 二值化 油画 卷积 锐化 高斯模糊
- 高级功能
- 手写数字识别
- 视频处理 – 多线程
- 二维码的生成识别 图片指纹 以图搜图
项目具体基本功能
- 读取图片:文件操作、IO异常try catch、BufferedImage 对象操作
- 操作界面:JFrame继承重写、初始化界面、按钮添加、添加监听器、画笔(Graphics)
- 图片原理:像素格式(RGB)、位移操作等
图片的原理
图片的存储
注意:在计算机中: 1 int = 4byte =32bit
- 一张图片的结构: 一些像素点
- 像素格式: R G B (0-255): 每个维度都以byte的格式存储
RGB例子
具体 —Red Green Blue
白色: 255 255 255
黑色: 0 0 0
红色: 255 0 0
黄色: 0 255 255
ARGB: 在RGB前,多了一个透明度(0就是透明,255就是不透明)
RGB默认是透明度为255的ARGB
ARGB列子
不透明红色: 255 0 0 255
透明黄色: 0 255 255 0
单独存储一个维度,是1byte, 4个维度就是4个byte =1个int,所以一般用一个int来存储一个像素值
1byte: 0000 0000 8bit
1int: 0000 0000 1000 0000 1000 0000 1000 0000 32bit
计算机是二进制的,在计算机中,RGB和ARGB是这么表示的
以RGB黄色,即透明度为255的ARGB黄色为例(均为4个byte )
RGB
0000 0000 0000 0000 1000 0000 1000 0000
ARGB
0000 0000 1000 0000 1000 0000 1000 0000
位移操作: 向右位移取出
int num=8,421,504;
byte red = num >> 16; (像右移16位,取出一个int大小的内容)
布尔:二进制逻辑运算
0000 0000 1000 0000 1000 0000 1000 0000 >> 8
= 0000 0000 0000 0000 1000 0000 1000 0000 & 只取对应位数的值 按位取
0000 0000 0000 0000 0000 0000 1111 1111
= 0000 0000 0000 0000 0000 0000 1000 0000
具体代码实现和结果
整数转三原色值
public void pixelToRGB(){
int num = 8421504;
int red = (num >> 16) & 0xFF;
System.out.println (red);
int green = (num >> 8) & 0xFF;
System.out.println (green);
int blue = (num >> 0) & 0xFF;
System.out.println (blue);
}
运行结果
得到图片缓存
public BufferedImage getImage(String path){
File file = new File (path);
System.out.println (file.getPath ());
BufferedImage image =null;
try {
image = ImageIO.read (file);
}catch (Exception e){
e.printStackTrace ();
}
return image;
}
根据 缓冲图片对象 转为一个 二维像素数组
public int[][] getImageArray(BufferedImage img){
int[][] imgarr = new int[img.getWidth ()][img.getHeight ()];
for(int i = 0; i < img.getWidth (); i++){
for(int j = 0; j < img.getHeight (); j++){
int rgb = img.getRGB (i, j);
imgarr[i][j] = rgb;
}
}
return imgarr;
}
根据数组绘制图片
public void paint(Graphics g){
super.paint(g);
BufferedImage img=getImage("C:\\Users\\ZLYLF\\Desktop\\cat.jpg");
g.drawImage(img,0,100,null);
int[][]imageArray=getImageArray(img);
drawImage01(imageArray,g);
}
UI类,继承于Jframe
public class DrawUI extends JFrame {
Drawlistener gl =new Drawlistener(this.getGraphics());
String [] butten_string_start ={"原图","灰度","二值化","随机马赛克","灵魂出窍","冷色","暖色","怀旧","铁砂网","美白","放大2倍","乐高","刷新","ARGB"};
DrawPanel drawPanel;
public void clear(){
this.drawPanel.paint(this.getGraphics());
}
public void initUI(){
JFrame jf =this;
jf.setDefaultCloseOperation(EXIT_ON_CLOSE);
jf.setTitle("美颜相机");
jf.setSize(2000,1000);
jf.setVisible(true);
JPanel buttonPanel =new JPanel();
buttonPanel .setBackground(Color.gray);
buttonPanel.setPreferredSize(new Dimension(150,0));
drawPanel =new DrawPanel();
drawPanel.setBackground(Color.GRAY);
drawPanel.setPreferredSize(new Dimension(this.getWidth()-150,0));
drawPanel.drawlistener = this.gl;
drawPanel.drawlistener.setGrawUI(drawPanel);
jf.add (buttonPanel,BorderLayout.EAST);
jf.add (drawPanel,BorderLayout.WEST
);
addButton(buttonPanel);
jf.setVisible (true);
drawPanel.addMouseListener(gl);
Graphics g = drawPanel.getGraphics ();
gl.setGraphics(g);
gl.ui=this;
}
public void addButton(JPanel buttonPanel){
Dimension dimension=new Dimension(150,50);
for(int i = 0; i < butten_string_start.length; i++){
JButton btn = new JButton (butten_string_start[i]);
btn.setPreferredSize(dimension);
buttonPanel.add (btn);
btn.addActionListener (gl);
}
}
class DrawPanel extends JPanel{
Drawlistener drawlistener;
@Override
public void paint(Graphics g){
super.paint (g);
}
}
public static void main(String[] args) {
new DrawUI().initUI();
}
}
监听器类,实现ActionListener(具体各种滤镜实现请看下一篇博客)
public class Drawlistener implements ActionListener {
Graphics gr;
DrawUI ui;
String graphics_type;
DrawUI.DrawPanel drawPanel;
BufferedImage image_display;
int[][]imageArray_display;
Drawlistener(Graphics gr){ this.gr =gr;}
public void setGraphics(Graphics graphics){
this.gr = graphics;
}
public void setGrawUI(DrawUI.DrawPanel drawPanel){
this.drawPanel = drawPanel;
}
public void refrash(){
this.drawPanel.paint(gr);
}
@Override
public void actionPerformed(ActionEvent e) {
String btnstr = e.getActionCommand ();
if (btnstr.equals("原图")){
graphics_type ="原图";
paint_original(gr);
}else if(btnstr.equals("灰度")){
graphics_type ="灰度";
draw_gray_Image(imageArray_display,gr);
}else if(btnstr.equals("二值化")){
graphics_type ="二值化";
draw_Image_binarization(imageArray_display,gr);
}else if(btnstr.equals("随机马赛克")){
graphics_type ="随机马赛克";
draw_Mosaic(gr);
}else if (btnstr.equals("冷色")){
graphics_type ="冷色";
draw_cold(gr);
}else if (btnstr.equals("暖色")){
graphics_type ="暖色";
draw_warm(gr);
}else if(btnstr.equals("灵魂出窍")){
graphics_type ="灵魂出窍";
draw_photo_negative(gr);
}else if(btnstr.equals("怀旧")){
graphics_type ="怀旧";
draw_oldimage(gr);
}else if(btnstr.equals("放大2倍")){
graphics_type ="放大2倍";
draw_bigger_2(gr);
}else if(btnstr.equals("美白")){
graphics_type ="美白";
draw_Whitening(gr);
}else if (btnstr.equals("铁砂网")){
graphics_type ="铁砂网";
draw_oil_painting(gr);
}else if (btnstr.equals("乐高")){
graphics_type ="乐高";
draw_LEGO(gr);
}else if (btnstr.equals("刷新")){
graphics_type ="刷新";
refrash();
}else if (btnstr.equals("ARGB")){
graphics_type ="ARGB";
draw_ARGB(gr);
pixelToRGB();
}
}
具体实现效果
Original: https://blog.csdn.net/qq_41025410/article/details/123595681
Author: 极客产品经理ZJH
Title: Java美颜相机(1)图像处理
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/642174/
转载文章受原作者版权保护。转载请注明原作者出处!