小浩浅谈之Java美颜相机pc端(视频)

在之前的文章中,给大家介绍了如果使用WebCamp来使用电脑的摄像头以及如何为图片添加各种滤镜,那么在这我们进行一个相互结合,就构成了一个我们pc端的美颜相机。

1.第一步和之前一样,就是框体 的创建,以及按钮的相关设置

public class Draw0211 {
    public void get(){
        JFrame jFrame=new JFrame();
        jFrame.setTitle("小浩美颜相机摄像");
        jFrame.setSize(800,900);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setLocationRelativeTo(null);
        BorderLayout borderLayout=new BorderLayout();
        jFrame.setLayout(borderLayout);
        //面板类对象的设定以及添加到窗体,和设置窗体的位置
        JPanel center=new JPanel();
        //颜色设定
        center.setBackground(Color.cyan);
        //设置爱完以后需要添加到窗体,否则无效
        jFrame.add(center,BorderLayout.CENTER);
        //监听器的设置
        Mouse0211 mouse0211=new Mouse0211();
        //开始定义菜单,菜单栏以及相关按钮
        JMenuBar jMenuBar=new JMenuBar();
        jFrame.add(jMenuBar,BorderLayout.NORTH);
        //定义在菜单栏中的菜单选项
        String[]name1={"文件","视频","图片","拍照","特殊滤镜","编辑","帮助"};
        //开辟一个menu数组来存储调用与添加
        JMenu[]menu=new JMenu[name1.length];
        for (int i=0;i< name1.length;i++) {
            JMenu jMenu = new JMenu(name1[i]);
            menu[i]=jMenu;
            jMenuBar.add(jMenu);
        }
        //子菜单中的菜单选项
        String[]name={"打开","关闭","退出"};
        for (int i=0;i<name.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[0].add(jMenuItem);
        }
        String[]name2={"打开摄像头","关闭摄像头","录制"};
        for (int i=0;i<name2.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name2[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[1].add(jMenuItem);
        }
        String[]name3={"原图","马赛克","灰度","油画","珠纹","素描"};
        for (int i=0;i<name3.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name3[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[2].add(jMenuItem);
        }
        String[]name4={"打开","关闭","保存"};
        for (int i=0;i<name4.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name4[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[3].add(jMenuItem);
        }
        String[]name5={"怀旧","梦幻","浮雕","卷积","哈哈镜"};
        for (int i=0;i<name5.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name5[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[4].add(jMenuItem);
        }
        String[]name6={"左旋转90度","右旋转90度","左旋转180度","右旋转180度"};
        for (int i=0;i<name6.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name6[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[5].add(jMenuItem);
        }
        String[]name7={"撤回"};
        for (int i=0;i<name7.length;i++) {
            JMenuItem jMenuItem = new JMenuItem(name7[i]);
            jMenuItem.addActionListener(mouse0211);
            menu[6].add(jMenuItem);
        }
        jFrame.setVisible(true);
        //画笔的传输
        mouse0211.graphicsmouse=center.getGraphics();
    }
    public static void main(String[] args) {
        Draw0211 draw0211=new Draw0211();
        draw0211.get();
    }
}

2.第二步通过监听器来获取按钮的点击,来获取调动命令,并对线程的启用以及滤镜的编写

public class Mouse0211  implements ActionListener {
    //画笔
    public Graphics graphicsmouse;
    //name来获取点击的名字
    public String name;
    //类来传递数据
    public Thread0211 thread0211;
    //监听器的接口方法使用
    public void actionPerformed(ActionEvent e){
        name=e.getActionCommand();
        System.out.println("正在点击的操作按钮为:"+name);
        if ("打开摄像头".equals(name)){
            //开始启动多线程,并且同时创建线程对象则显示线程创建一次
            if (thread0211==null){
                thread0211=new Thread0211(graphicsmouse,this);
                //开始启动线程
                thread0211.start();
            }
        }else if ("关闭摄像头".equals(name)){
            thread0211.flag=false;
            System.out.println("关闭");
        }if("原图".equals(name)){
            thread0211.name="原图";
        }if ("灰度".equals(name)){
            thread0211.name="灰度";
        }if ("马赛克".equals(name)){
            thread0211.name="马赛克";
        }if ("油画".equals(name)){
            thread0211.name="油画";
        }if ("哈哈镜".equals(name)){
            thread0211.name="哈哈镜";
        }if ("珠纹".equals(name)){
            thread0211.name="珠纹";
        }if ("素描".equals(name)){
            thread0211.name="素描";
        }
    }
    //灰度算法
    public BufferedImage drawHD(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i < pixelArr.length; i++) {
            for (int j = 0; j < pixelArr[0].length; j++) {
                // 像素值
                int pixel = pixelArr[i][j];
                // 马赛克,灰度,底片
                // 转成Color对象,设置给画笔,画出像素点
                Color color = new Color(pixel);
                // 取出三原色
                int red = color.getRed();
                int blue = color.getBlue();
                int green = color.getGreen();
                // 算法平均值
                int num = (red + blue + green) / 3;
                Color pixelColor = new Color(num, num, num);
                //设置缓冲区的像素值
                bufferedImage.setRGB(i, j, pixelColor.getRGB());
                // 把像素点画在缓冲图片上
//                buffG.setColor(pixelColor);
//                buffG.drawLine(i + 100, j + 100, i + 100, j + 100);
            }
        }
        return bufferedImage;
    }
    //马赛克算法
    public BufferedImage drawMSK(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i < pixelArr.length; i += 3) {
            for (int j = 0; j < pixelArr[0].length; j += 3) {
                // 像素值
                int pixel = pixelArr[i][j];
                // 把像素点画在缓冲图片上
                buffG.setColor(new Color(pixel));
                buffG.fillRect(i, j, 10, 10);
            }
        }
        return bufferedImage;
    }
    //哈哈镜算法
    public BufferedImage drawHHJ(int x,int y,int[][] pixelArr) {;
        int w= pixelArr.length;
        int h= pixelArr[0].length;
        //计算中心点位置
        int zx=x-100;
        int zy=y-100;
        //放大半径,自己设置
        int r=100;
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(w,
                h, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i <w; i++) {
            for (int j = 0; j <h;j++) {
                //计算当前位置是否在中心位置
                int tx=i-zx;
                int ty=j-zy;
                //当前点到中心点的距离
                int dis=(int) Math.sqrt(tx*tx+ty*ty);
                if (dis<r){
                    //越靠近中心点,偏移量越大
                    int nx=tx*dis/r+zx;
                    int ny=ty*dis/r+zy;
                    bufferedImage.setRGB(i,j,pixelArr[nx][ny]);
                }
            }
        }
        return bufferedImage;
    }
    //油画算法
    public BufferedImage drawYH(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i < pixelArr.length; i++) {
            for (int j = 0; j < pixelArr[0].length; j++) {
                int pixel = pixelArr[i][j];
                Color color = new Color(pixel);
                buffG.setColor(color);
                Random random = new Random();
                int r = random.nextInt(10) + 5;
                buffG.fillOval(i, j, r, r);
            }
        }
        return bufferedImage;
    }
    //珠纹算法
    public BufferedImage drawZW(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i < pixelArr.length; i += 4) {
            for (int j = 0; j < pixelArr[0].length; j += 4) {
                int pixel = pixelArr[i][j];
                Color color = new Color(pixel);
                buffG.setColor(color);
                buffG.fillOval(i, j, 8, 8);
            }
        }
        return bufferedImage;
    }
    //素描算法
    public BufferedImage drawSM(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        for (int i = 0; i < pixelArr.length; i += 2) {
            for (int j = 0; j < pixelArr[0].length; j += 2) {
                int pixel = pixelArr[i][j];
                Color color = new Color(pixel);
                int b = color.getBlue();
                if (b < 60) {
                    buffG.setColor(Color.black);
                } else {
                    buffG.setColor(Color.WHITE);
                }
                buffG.fillOval(i, j, 4, 4);
            }
        }
        return bufferedImage;
    }
    //旋转算法
    public BufferedImage drawXZ(int[][] pixelArr) {
        //创建缓冲区
        BufferedImage bufferedImage = new BufferedImage(pixelArr.length,
                pixelArr[0].length, BufferedImage.TYPE_INT_RGB);
        // 获取缓冲区画笔
        Graphics buffG = bufferedImage.getGraphics();
        int[][] newArr = new int[pixelArr[0].length][pixelArr.length];
        for (int i = 0, n = pixelArr.length - 1; i < pixelArr.length; i++, n--) {
            for (int j = 0; j < pixelArr[0].length; j++) {
                newArr[j][n] = pixelArr[i][j];
            }
        }
        return bufferedImage;
    }
}

3.线程类,并通过按钮调动滤镜算法

public class Thread0211 extends Thread {
    //画笔初始化
    public Graphics graphicsthread;
    //flag做标记来实现开关视频
    public boolean flag = true;
    //flag做标记来实现开关视频
    public int flag1 = 0;
    //滤镜名称
    public String name="原图";
    //类的对象构造
    public Mouse0211 mouse11;
    //处理后的缓冲图片
    public BufferedImage buffered;

    //构造方法进行参数的传递,初始化画笔对象
    public Thread0211(Graphics graphicsthread, Mouse0211 mouse11) {
        this.graphicsthread = graphicsthread;
        this.mouse11 = mouse11;
    }

    //处理线程,启动线程后运行的程序,run 方法执行完,该线程结束,线程一旦结束不能再次启动
    public void run() {
        //这个this给到的是什么
        System.out.println("启动线程.." + this.getName());
        //启动摄像头,在这个线程中使用
        Webcam webcam = Webcam.getDefault();
        webcam.open();
        while (flag) {
            // 获取摄像头拍到的数据
            BufferedImage bufferedImage = webcam.getImage();
//            if (name.equals("原图")) {
//                graphicsthread.drawImage(bufferedImage, 100, 100, 500, 400, null);
//            }
//            if (name.equals("灰度")) {
//                int[][] pixel = getImagePixel(bufferedImage);
//                buffered = mouse11.drawHD(pixel);
//                break;
//            }
//            if (name.equals("马赛克")){
//                    int[][] pixel = getImagePixel(bufferedImage);
//                    buffered = mouse11.drawMSK(pixel);
//                    System.out.println("222222222222222222");
//                    break;
//            }
            switch (name) {
                case "原图":
                    graphicsthread.drawImage(bufferedImage, 100, 100, 600,600,null);
                    break;
                case "灰度":
                    int[][] pixel = getImagePixel(bufferedImage);
                    buffered =mouse11.drawHD(pixel);
                    break;
                case "马赛克":
                    int[][] pixel1 = getImagePixel(bufferedImage);
                    buffered = mouse11.drawMSK(pixel1);
                    break;
                case "哈哈镜":
                    int[][] pixel2 = getImagePixel(bufferedImage);
                    buffered = mouse11.drawHHJ(200,200,pixel2);
                    break;
                case "油画":
                    int[][] pixel3 = getImagePixel(bufferedImage);
                    buffered = mouse11.drawYH(pixel3);
                    break;
                case "珠纹":
                    int[][] pixel4 = getImagePixel(bufferedImage);
                    buffered = mouse11.drawZW(pixel4);
                    break;
                case "素描":
                    int[][] pixel5 = getImagePixel(bufferedImage);
                    buffered = mouse11.drawSM(pixel5);
                    break;
            }
            //绘制滤镜效果
            graphicsthread.drawImage(buffered, 100, 100,600,600, null);
            if (name.equals("保存")){
                //保存图片的文件
                File file=new File("");
                try {
                    ImageIO.write(buffered,"PNG",file);
                    break;
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    public int[][] getImagePixel(BufferedImage buffImage) {
            int w = buffImage.getWidth();
            int h = buffImage.getHeight();
            int[][] pixelArr = new int[w][h];
            // 获取图片中的每一个像素值保存到二维数组中
            for (int i = 0; i < w; i++) {
                for (int j = 0; j < h; j++) {
                    int pixel = buffImage.getRGB(i, j);
                    pixelArr[i][j] = pixel;
                }
            }
            return pixelArr;
        }
}

4.效果如下(菜单栏中些许功能没有完善,后续会继续完善)

 

 

 

(马赛克,油画,灰度,哈哈镜效果) 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个实现在移动端HTML中调用摄像头并支持美颜的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Camera Beauty</title> <style> #videoElement { width: 100%; height: auto; max-width: 600px; margin: 0 auto; } </style> </head> <body> <video id="videoElement"></video> <script> // 获取video元素 const video = document.getElementById('videoElement'); // 判断是否支持调用摄像头 if (navigator.mediaDevices.getUserMedia) { // 调用摄像头 navigator.mediaDevices.getUserMedia({ video: true }) .then(function (stream) { // 将摄像头渲染到video元素中 video.srcObject = stream; }) .catch(function (error) { console.log("Something went wrong!"); }); } // 美颜滤镜 const setFilter = () => { // 创建canvas元素,用于渲染滤镜效果 const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; context.drawImage(video, 0, 0, canvas.width, canvas.height); const imageData = context.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { let r = data[i]; let g = data[i + 1]; let b = data[i + 2]; data[i] = (r * 0.393) + (g * 0.769) + (b * 0.189); data[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168); data[i + 2] = (r * 0.272) + (g * 0.534) + (b * 0.131); } context.putImageData(imageData, 0, 0); // 将滤镜效果渲染到video元素中 video.style.backgroundImage = `url(${canvas.toDataURL()})`; }; // 调用美颜滤镜 video.addEventListener('play', () => { setInterval(setFilter, 10); }, false); </script> </body> </html> ``` 其中,通过 `navigator.mediaDevices.getUserMedia` 方法调用摄像头,将摄像头渲染到 `<video>` 元素中;通过 `setFilter` 方法实现美颜滤镜效果,并将滤镜效果渲染到 `<video>` 元素中。最终实现在移动端HTML中调用摄像头并支持美颜的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网友小浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值