美颜相机的基本功能实现

news/2024/10/31 1:27:25/

美颜相机的基本功能实现

基本知识

在学习了在标准绘制图形库中进行简单的递归图像实现后,我们把目光聚焦到了对于复杂图片文件的处理上,在这里需要简单介绍一下关于图像色彩的知识,以及缓存图片类的介绍。

图形色彩参数“ARGB”

在一个复杂图片文件中,不管图片的大小和整体的色彩有何等的差异,它都可以被拆分成一个个小的像素块,每个像素块具有A:透明度,R:红色参数,G:绿色参数,B:蓝色参数,由于红绿蓝三种颜色的组合可以匹配所有的颜色,所以运用这四个参数,可以标识一个像素块的颜色情况,在实际编码过程中,正向设置各个参数比较容易,问题是在一张已有的图片中获取某个像素块的四个参数比较困难,虽然有库方法getRed以及其他方法可以直接调用获取参数,但在这里我想简要介绍一下通过位运算实现对像素点颜色参数获取:

位运算

在计算机中对于一个像素点的色彩信息存储是通过一个32位8比特的二进制码存储,每两个比特存储一个颜色参数(ARGB依次按照顺序从前到后存储),当我们想分别获取A,R,G,B的参数值时,等价于获取这串二进制码中的某一部分,这里运用二进制码中原码,反码与补码的关系,可以实现对这串二进制码的部分提取(运用与运算)。如下

int num=8421504;//某一像素点二进制码对应的十进制数,像素点自带的参数
int red=(num>>16)&0xFF;//“>>"表示把操作位进行向右移动,同时低位被舍去
//0xFF指代的是二进制码全为1
//与运算逻辑是对比每一位,相同时保留数字,不同时为0,
//因此可以选出特定位置的二进制码
int green=(num>>8)&0xFF;
int blue=(num>>0)&0xFF;

缓存图片的使用

在对图片进行操作时,一般不能直接对图片进行操作,需要我们在内存中创建一个缓存图片,用来提高对像素点数据的获取,以及获取像素点参数的效率,我们通过IO流的使用实现从图片文件到缓存文件的获取:

public class BeautifyUtils {static ArrayList<Order> range=new ArrayList<>();Graphics g;public static 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 void IninUI(){JFrame jf=new JFrame();jf.setTitle("美颜相机");jf.setSize(1000,750);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//添加面板JPanel imgshowPanel =new JPanel();JPanel btnPanel =new JPanel();//设置面板的相关属性imgshowPanel.setBackground(Color.GRAY);btnPanel.setBackground(Color.LIGHT_GRAY);Dimension dim=new Dimension(200,0);btnPanel.setPreferredSize(dim);//只有窗体是setsizethis.SetButton(btnPanel);jf.add(btnPanel,BorderLayout.EAST);//此处采用边框布局,即设置东南西北方向和中心位置//,顺序原则是先东西,再南北,最后剩余的在中部//注意此处是给btnPanel赋值长度,add时应该按照先btn再img的顺序,不可颠倒,否则无法布置位置jf.add(imgshowPanel,BorderLayout.CENTER);jf.setVisible(true);//gr是局部变量,需要同步进行收集变量和传出变量Graphics gr=imgshowPanel.getGraphics();BeautifyListener.bft.g=gr;//把画笔传给监听器}

监听器的实现

public class BeautifyListener extends MouseAdapter implements ActionListener {static ArrayList<Order> range=new ArrayList<>();//用于之后图片效果撤回的链表,可以暂时不管//后面会给予说明Graphics g;static BeautifyListener bft =new BeautifyListener();//注意使用到静态方法,表明创建的对象唯一BeautifyUtils beautifyUtils =new BeautifyUtils();BufferedImage buffimg=null;int [][] imgarr={};{//代码块初始化(创建对象时运行,且只调用一次)buffimg=BeautifyUtils.getImage("C:\\Users\\Lenovo\\Desktop\\Mouse.jpg");//这里的图片可以自行修改,格式是路径\\文件名.文件类型imgarr =BeautifyUtils.getImageArray(buffimg);//获取缓存图片中的参数二维数组}@Overridepublic void actionPerformed(ActionEvent e) {//功能以及判断的插入}

按钮的创建和与监听器的链接

public void SetButton(JPanel jp){String[] btnstr = {"原图","美白","马赛克","灰度","反转","油画","撤回","保存"};//注意这种方便的字符串数组运用于按钮名的创立Dimension dim =new Dimension(90,25);for (int i = 0; i < btnstr.length; i++) {JButton jb=new JButton();jb.setText(btnstr[i]);//不能直接赋值就创立对象后命名jb.setBackground(Color.WHITE);jb.setPreferredSize(dim);jb.addActionListener(BeautifyListener.bft);jp.add(jb);}}//Order 对象的建立,存储功能代号
//在监听器方法actionPerformed中:
String btnstr =e.getActionCommand();//获取鼠标点击的按钮对应的文本if(btnstr.equals("原图")){//进行判断,不用害怕这么长的代码//大部分是重复的判断语句以及对相应功能方法的调用Order order=new Order();//order.num=1;range.add(order);BeautifyUtils.drawImage(g,buffimg);}else if(btnstr.equals("美白")){Order order=new Order();//每次创立一个顺序对象order.num=2;//存储功能代号range.add(order);BeautifyUtils.drawImage02(g,imgarr);//调用功能}else if(btnstr.equals("马赛克")){Order order=new Order();order.num=3;range.add(order);BeautifyUtils.drawImage03(g,imgarr);}else if(btnstr.equals("灰度")){Order order=new Order();order.num=4;range.add(order);BeautifyUtils.drawImage04(g,imgarr);}else if(btnstr.equals("反转")){Order order=new Order();order.num=5;range.add(order);BeautifyUtils.drawImage05(g,imgarr);}else if(btnstr.equals("油画")){Order order=new Order();order.num=6;range.add(order);BeautifyUtils.drawImage06(g,imgarr);}else if(btnstr.equals("撤回")){if(range.size()<=1){//是否为空的判断JOptionPane.showMessageDialog(null,"此时不可再撤回");//设置提示窗return;}range.remove(range.size()-1);Order last=range.get(range.size()-1);//移除链表中的一个操作代号,返回到上一个操作//判断上一操作的功能if(last.num==1){BeautifyUtils.drawImage(g,buffimg);}else if(last.num==2){BeautifyUtils.drawImage02(g,imgarr);}else if(last.num==3){BeautifyUtils.drawImage03(g,imgarr);}else if(last.num==4){BeautifyUtils.drawImage04(g,imgarr);}else if(last.num==5){BeautifyUtils.drawImage05(g,imgarr);}else if(last.num==6){BeautifyUtils.drawImage06(g,imgarr);}}else if(btnstr.equals("保存")){}

功能方法

获取缓存图片二维数组

public static int[][] getImageArray(BufferedImage image){int [][]rgbArray=new int[image.getWidth()][image.getHeight()];for(int i=0;i<image.getWidth();i++){for(int j=0;j<image.getHeight();j++){int rgb=image.getRGB(i,j);rgbArray[i][j]=rgb;//这里的rgb是我们之前提及的//32位存储颜色参数的二进制码}}return rgbArray;}

原图展示

public static void drawImage(Graphics g,BufferedImage buffimg){g.drawImage(buffimg,0,0,null);//使用从监听器中传来的//画笔绘制缓存图片}

美白

public static void drawImage02(Graphics g,int [][]imgarr){Order order=new Order();order.num=2;range.add(order);//存储操作代号,用于撤回,后面不给予说明for(int i=0;i<imgarr.length;i++){for(int j=0;j<imgarr[i].length;j++){//注意二维数组的长度获取Color old=new Color(imgarr[i][j]);int red=old.getRed();int green=old.getGreen();int blue= old.getBlue();//此处同样可以采用位运算,为了方便调用方法if(red<245&&green<245&&blue<245) {//注意不要越界(最大值为255,三者越靠近255,颜色越亮)Color now = new Color(red + 10, green + 10, blue + 10);//美白效果的rgb处理,整体调亮g.setColor(now);//注意此处必须先创立颜色对象}else{//越界处理g.setColor(old);}g.fillRect(i,j,1,1);}}}

马赛克效果

    public static void drawImage03(Graphics g,int [][]imgarr){Order order=new Order();order.num=3;range.add(order);for(int i=0;i<imgarr.length;i+=5){for(int j=0;j<imgarr[i].length;j+=5){Color c =new Color(imgarr[i][j]);int red=c.getRed();int green=c.getGreen();int blue=c.getBlue();Color co =new Color(red,green,blue);g.setColor(co);g.fillRect(i,j,5,5);//放大像素块,达到马赛克效果}}}

灰白化

public static void drawImage04(Graphics gr,int [][]imgarr) {Order order=new Order();order.num=4;range.add(order);for (int i = 0; i < imgarr.length; i++) {for (int j = 0; j < imgarr[i].length; j++) {Color old = new Color(imgarr[i][j]);int r = old.getRed();int g = old.getGreen();int b = old.getBlue();int sum = (r + g + b) / 3;//平均色彩参数Color now = new Color(sum, sum, sum);//灰白化gr.setColor(now);gr.fillRect(i, j, 1, 1);}}}

反转

public static void drawImage05(Graphics gr,int [][]imgarr){Order order=new Order();order.num=5;range.add(order);for(int i=0;i<imgarr.length;i++){for(int j=0;j<imgarr[i].length;j++){Color old =new Color(imgarr[i][j]);int r= old.getRed();int g=old.getGreen();int b=old.getBlue();Color now =new Color(255-r,255-g,255-b);gr.setColor(now);gr.fillRect(i,j,1,1);}}}

油画

public static void drawImage06(Graphics gr,int [][]imgarr){Order order=new Order();order.num=6;range.add(order);for(int i=0;i<imgarr.length;i+=3){for(int j=0;j<imgarr[i].length;j+=3){Color now =new Color(imgarr[i][j]);gr.setColor(now);Random ran =new Random(66);//获取像素块长宽的随机值,//达到油画效果,虽然个人觉得与马赛克区别不大gr.fillRect(i,j,ran.nextInt(5)+3,ran.nextInt(5)+3);}}}
}

实现的效果

原图
原图
灰白化
灰白
反转(慎看)
反转
油画
油画
至此对于美颜相机的简单功能的实现就完成了,对于功能过程中的卡顿和是图片的闪卡问题,我们将在之后进一步优化。


http://www.ppmy.cn/news/437093.html

相关文章

linux 相机软件,镜像相机app

镜像相机app带给用户更多特别的拍摄滤镜和效果&#xff0c;这里提供了两种拍摄方式&#xff0c;一种是普通的拍摄效果&#xff0c;还有一种拍摄出来的是左右镜面对称的效果&#xff0c;并且镜像相机app中随时可以进行图片编辑和美化功能&#xff0c;强大的修图和丰富的滤镜贴纸…

补充 | 美颜相机卡顿trace分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、美颜相机录制视频 trace 分析概览二、Camera FWK 与 camera HAL 录像交互三、美颜相机app 与SurfaceFlinger 交互四、美颜相机卡顿丢帧trace 分析 …

Java程序结构模板——美颜相机案例

我们以美颜相机举例&#xff0c;分析一个程序都需要什么。 1、UI界面&#xff1a;大部分需要交互的程序都需要UI界面来实现交流互动。 2、监听器&#xff1a;人们在UI中的操作需要监听器来捕捉和执行相应的命令。 3、工具类&#xff1a;将执行命令的方法单独封装成工具类&#…

P8美颜相机的实现

美颜相机 一. 基础知识二. 图片处理将一个图片转化为一个二维数组并封装 三.写一个界面并添加画板和按钮四. 添加监听器并将图片信息传递给监听器中五.马赛克六.灰度七.素描美白油画轮廓检测 一. 基础知识 一幅图就是无数个像素点组成&#xff0c;可以看成宽w高h的二维数组图像…

大疆口袋相机美颜怎么设置_大疆(DJI)Pocket2 | 深度测评口袋相机:超多配件随心搭,自带美颜的拍摄助手!-极果...

写在前面 你真的需要一台DJI Pocket 2吗?嘿,大家好~我是抖音博主无情剪辑狗,作为一名摄影教学类博主很高兴能体验到DJI Pocket 2,经过自己一个星期的体验,来和大家分享一下这款产品我的心得体会以及什么样的人适合入手这样一台设备。 下面通过这则视频可以先简单的了解一…

基于OpenCV和OpenGL 的简易美颜相机

版本信息 AndroidStudio 3.5.2 OpenCV 4.1.2 OpenGL 2 OpenCV是什么 维基百科 在本Demo中&#xff0c;OpenCV实现面部识别功能 OpenGL是什么 维基百科 在本Demo中&#xff0c;OpenGL实现美颜功能 配置OpenCV环境 在AndroidStudio中新建C项目 下载OpenCV Android版 …

美颜相机的设计与实现

美颜相机的实现&#xff08;利用Webcam&#xff09; 如何实现美颜相机&#xff1f; 首先&#xff0c;需要导入三个外部jar包来调用摄像头 美颜相机是要调用我们的电脑摄像头实时获取我们的视频数据&#xff0c;视频就是由一帧一帧的图片组成的&#xff0c;所以我们需要先将一…

java简易美颜相机

一、图片处理的原理 首先我们知道数码照片只要是存储在计算机上的内容都是二进制码组成&#xff0c;而图片RGB值是由三组byte组成的&#xff08; 255.0.0&#xff08;红色&#xff09;&#xff09;&#xff0c;所以它可以看成一个整数&#xff0c;红色即为&#xff1a;1671168…