Java美颜相机(1)图像处理

图像处理美颜相机——基本功能实现

项目完整知识点(这里只实现了基本功能)

  • 基本功能
    • 图像原理 像素 矩阵 二进制位运算 十进制 十六进制
    • 基本的文件操作 读取照片 保存照片
    • 界面开发 - 优化 自适应操作 刷新 图层、监听器
    • 图像算法 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 ());
        // 先声明一个缓冲图片 img
        BufferedImage image =null;
        try {

            // IO操作 读取到的缓冲图片对象赋给 img
            image = ImageIO.read (file);
        }catch (Exception e){
            e.printStackTrace ();
        }
        // 方法返回值 img 对象
        return image;
    }
根据 缓冲图片对象 转为一个 二维像素数组
public int[][] getImageArray(BufferedImage img){
        // 根据图片的宽高 初始化一个二维数组
        int[][] imgarr = new int[img.getWidth ()][img.getHeight ()];
        // img 对象可以调用的方法
        // 遍历存入 img 对象中取出的像素值
        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 {

    //把窗口的画笔传给listener
    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(){
        //把drawUI的 窗体给新的窗体
        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;
    }
    //  设置drawPanel 方便刷新
    public void setGrawUI(DrawUI.DrawPanel drawPanel){
        this.drawPanel = drawPanel;
    }
    //  刷新画板,即调用paint方法
    public void refrash(){
        this.drawPanel.paint(gr);
    }

    /**
     * @param e 按钮事件
     * 按钮事件
     */
    @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();
        }

    }
具体实现效果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值