java实现美颜相机

看下实现效果

准备工作我们需要导入webcam包

##  视频图像获取:
http://webcam-capture.sarxos.pl/  

## 导包: 
- Eclipse :
  - * 项目:
  - 1: 右键项目名 Build Path - Config BuildPath - Lib - add Jars 选中
- IDEA :
  - 1:右键项目名 Module Setting   
  - 2:找到 lib -> +号 Java 选中jar包

实现代码

1videoui类

public class VideoUI extends JFrame {
    public VideoUI(){
        setTitle("图像处理");
        setSize(1000,1000);
        setDefaultCloseOperation(3);

        //设置流式布局
        setLayout(new FlowLayout());
        VideoListener vl = new VideoListener();
        addButton (vl);
        setVisible(true);
        //摄像头
        /*只有一个时: */
        Webcam webcam = Webcam.getDefault();
        webcam.setViewSize(WebcamResolution.VGA.getSize());
        webcam.open();

        PlayVideo playVideo = new PlayVideo();
        //得将playVIdeo 传到监听器当中去
        vl.playVideo = playVideo;

        //这是死循环,之后不能再写代码
        playVideo.runVideo(webcam,getGraphics());
        //后面不能加代码

    }

    public void addButton(VideoListener vl){
        // 先定义一个字符串数组 存储所有按钮的字符串
        String[] btnstrs = {
                "原图","马赛克","刷新图片", "反片", "脸部提亮", "灰度", "二值化", "美白", "油画", "轮廓提取", "撤回","暖色系","冷色系","珠纹化"
        };
        for(int i = 0; i < btnstrs.length; i++){
            String btnstr = btnstrs[i];
            JButton btn = new JButton (btnstr);
            add (btn);
            // 按钮添加监听器
            btn.addActionListener (vl);
        }
    }


    public static void main(String[] args) {
        new VideoUI();
    }

}

2videolistener类

public class VideoListener implements ActionListener {
    PlayVideo playVideo;
 
    @Override
    public void actionPerformed(ActionEvent e) {
        String btnstr = e.getActionCommand();
        //点击按钮之后,修改死循环中的判断所用到的变量的值
        playVideo.btnstr=btnstr;
        System.out.println("点击了"+btnstr);
    }
}

3playvideo类

public class PlayVideo {
    //定义一个属性 按钮文本
    String btnstr="";      //得给一个默认值,不然提示报错为空;
//VideoEff 视频效果对象imageEff 
    VideoEff imageEff = new VideoEff();
    /*
    *播放视频
    */
    public void runVideo(Webcam webcam, Graphics g){
        //用死循环来一帧一帧处理图片
        while (true){
        //1、获取图片
            BufferedImage img = webcam.getImage();
            int [][]imagePixArray = imageEff.getImagePixArray(img);
        //2、判断如何处理图片
        if(btnstr.equals("原图")){
            //不需要处理
            g.drawImage(img,100,100,null);
        }
        if(btnstr.equals("马赛克")){
            //传入图像数组,图片对象,视频效果对象调用该类中的方法来绘制
            imageEff.drawImage_02(imagePixArray,g);
        }
            if(btnstr.equals ("反片")){
                imageEff.drawImage_03(imagePixArray,g);
            }
            if(btnstr.equals ("脸部提亮")){
                imageEff.drawImage_04(imagePixArray,g);
            }
            if(btnstr.equals ("灰度")){
                imageEff.drawImage_05(imagePixArray,g);
            }
            if(btnstr.equals ("二值化")){
                imageEff.drawImage_06(imagePixArray,g);
            }
            if(btnstr.equals ("油画")){
                imageEff.drawImage_08(imagePixArray,g);
            }
            if(btnstr.equals ("轮廓提取")){
                imageEff.drawImage_09(imagePixArray,g);
            }
            if(btnstr.equals("珠纹化")) {
                imageEff.drawImage_13(imagePixArray,g);
            }
        }
    }
}

4videoeff类

public class VideoEff {
    //图片绘制坐标的参数
    final int X=100;
    final int Y=100;
 
    /**
     * 将一张图片转为二位数
     *
     * @param buffimg
     *         缓冲图片对象
     * @return 存有图片像素值的二维数组
     */
 
 
 
    public int[][] getImagePixArray(BufferedImage buffimg) {
 
        // 获取图片尺寸
        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;
    }
 
 
 
//————————————————————————————————————————————————————————————————————————————————————
 
//以下是绘制图片效果部分
 
 
    /**
     * 1、绘制原图方法
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     */
 
    public BufferedImage drawImage_01(int[][] imgarr,Graphics g) {
 
        BufferedImage img = new BufferedImage(imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
        // 如何不绘制特殊形状, 可以考虑直接设置RGB
        for(int i=0;i<imgarr.length;i++) {
            for(int j=0;j<imgarr[i].length;j++) {
                int rgb = imgarr[i][j];
                //将RGB	遍历存入BufferedImage;
                img.setRGB(i,j,rgb);
            }
        }
        
        g.drawImage(img,X,Y,null);
        return img;
    }
 
 
 
     * 2、马赛克:每隔几个点取几个像素,并将图像放大 只需要在原图基础上设置取点位置以及放大g的宽和高
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     */
    public BufferedImage drawImage_02(int[][] imgarr,Graphics g) {
 
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
        //获取缓冲区画
//        g = img.getGraphics();
 
        for(int i=0;i<imgarr.length;i+=10) {
            for(int j=0;j<imgarr[i].length;j+=10) {
                int rgb = imgarr[i][j];
 
                Color color =new Color(rgb);
 
                g.setColor(color);
                g.fillRect(X+i,Y+j,10,10);
            }
        }
        g.drawImage(img,X,Y,null);
 
        return img;
    }
 
 
    /**
     * 3、反片  利用获取颜色255-red,255-green,255-blue来做处理
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     */
    public BufferedImage drawImage_03(int[][] imgarr,Graphics g) {
        //创建缓冲图片
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
//        Graphics g1 = img.getGraphics();
 
        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 blue = color.getBlue();
                int green = color.getGreen();
                Color ncolor =new Color(255-red,255-green,255-blue);
 
                g.setColor(ncolor);
                g.fillRect(X+i,Y+j,1,1);
            }
        }
        g.drawImage(img,X,Y,null);
 
        return img;
    }
 
    /**
     * 4、脸部提亮
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     * @return
     */
    public BufferedImage drawImage_04(int[][] imgarr,Graphics g) {
 
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
        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 blue = color.getBlue();
                int green = color.getGreen();
 
 
                int grey = (int)(red*0.299+green*0.587+blue*0.114);
 
                Color ncolor = new Color(Math.abs(red-255+245),green,blue);
                g.setColor(ncolor);
                g.fillRect(X+i,Y+j,1,1);
            }
        }
        g.drawImage(img,X,Y,null);
        return img;
    }
 
    /**
     * 5、灰度处理
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     * @return
     */
    public BufferedImage drawImage_05(int[][] imgarr,Graphics g) {
        //创建缓冲图片
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
        //获取缓冲区笔
 
        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 blue = color.getBlue();
                int green = color.getGreen();
 
                //int grey = (int)(red+blue+green)/3;     较为简单的方法
//		RGB转换成灰度图像的方法
//	    Gray = R*0.299 + G*0.587 + B*0.114
 
              
                //更精确的表示
                int grey = (int)(red*0.299+green*0.587+blue*0.114);
 
                Color ncolor = new Color(grey,grey,grey);
 
                g.setColor(ncolor);
 
                g.fillRect(X+i,Y+j,1,1);
            }
        }
        g.drawImage(img,X,Y,null);
        return img;
    }
 
    /**
     * 6、二值化
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     * @return
     */
    public BufferedImage drawImage_06(int[][] imgarr,Graphics g) {
 
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
 
        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 blue = color.getBlue();
                int green = color.getGreen();
                
//先进行灰度化处理
                int grey = (int)(red*0.299+green*0.587+blue*0.114);
                Color ncolor = new Color(grey,grey,grey);
//用灰度值大小与110进行比较(修改参数值可以得到不同的深浅度)
                if(grey <110)
                {
                    g.setColor (Color.BLACK);
                }
                else{
                    g.setColor (Color.WHITE);
                }
                g.fillRect (100 + i, 100 + j, 1, 1);
            }
        }
        g.drawImage(img,X,Y,null);
 
        return img;
    }
 
 
    /**
     * 8、油画
     * @param imgarr 图片数组
     * 原理:每隔五个像素点取一个,然后用随机大小的椭圆填充每个像素点周围的区域
     * @param g 图像画笔对象
     * return
     */
 
 
    public BufferedImage drawImage_08(int[][] imgarr,Graphics g) {
 
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
        for(int i=0;i<imgarr.length-5;i+=5) {
            for(int j=0;j<imgarr[i].length-5;j+=5) {
                int rgb = imgarr[i][j];
                Color color =new Color(rgb);
 
                g.setColor(color);
 
                Random ran=new Random();
 
                int r=ran.nextInt(20)+5;
 
                g.fillOval(X+i,Y+j,r,r);
            }
        }
        g.drawImage(img,X,Y,null);
        return img;
    }
 
    /**
     * 9、轮廓处理
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     * @return
     */
    public BufferedImage drawImage_09(int[][] imgarr, Graphics g){
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
 
        for(int i = 0; i < imgarr.length-1; i++){
            for(int j = 0; j < imgarr[i].length-1; 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.41 + green * 0.36 + blue * 0.23);
 
                // 取出右下斜方向的像素按照 灰度值 作比较
                int nrgb = imgarr[i + 1][j + 1];
                Color ncolor = new Color (nrgb);
                int nred = ncolor.getRed ();
                int ngreen = ncolor.getGreen ();
                int nblue = ncolor.getBlue ();
                int ngray = (int) (nred * 0.41 + ngreen * 0.36 + nblue * 0.23);
 
                if(Math.abs (gray - ngray) > 15){
                    g.setColor (Color.black);
                } else{
                    g.setColor (Color.white);
                }
                g.fillRect (X + i, Y + j, 1, 1);
            }
        }
        g.drawImage(img,X,Y,null);
        return img;
    }
 
  
    /**
     * 13、珠纹化
     * @param imgarr 图片数组
     * @param g 图像画笔对象
     * 原理,每隔10取一个像素点,后用大小为9的圆填充
     */
    public BufferedImage drawImage_13(int[][] imgarr,Graphics g) {
        BufferedImage img = new BufferedImage (imgarr.length,imgarr[0].length,BufferedImage.TYPE_INT_ARGB);
 
        for(int i=0;i<imgarr.length;i+=10) {
            for(int j=0;j<imgarr[i].length;j+=10) {
                int rgb = imgarr[i][j];
                Color color =new Color(rgb);
                g.setColor(color);
                g.fillOval(X+i,Y+j,9,9);
            }
        }
        g.drawImage(img,X,Y,null);
        return img;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值