小浩浅谈如何为图片提供滤镜功能
近些天,一直想做一个pc版的美颜相机,但是万事开头总要有第一步,首先就是美颜相机的添加滤镜问题,直接上手视频未免过于着急,于是就想先对单张图片来实现滤镜功能的添加。
1.第一步,就是窗体和面板的创立,以及相关监听器的添加和画笔的传递
public class EDrawUI {//定义方法public void init() {//绘制窗体基本JFrame jf = new JFrame();jf.setSize(810, 900);jf.setTitle("小浩的美颜相机3.9");jf.setLocationRelativeTo(null);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//布局的确定BorderLayout border = new BorderLayout();jf.setLayout(border);//确定north与centerJPanel jp_north=new JPanel();jp_north.setBackground(Color.white);Dimension ds_north=new Dimension(0,40);jp_north.setPreferredSize(ds_north);jf.add(jp_north,BorderLayout.NORTH);//加入一个使用的CmyPanel面板EMyPanel center=new EMyPanel();center.setBackground(Color.white);jf.add(center,BorderLayout.CENTER);//监听器对象的创立EPixelMouse ePixelMouse=new EPixelMouse();//开始设置菜单栏JMenuBar jmu=new JMenuBar();jp_north.add(jmu);//设置菜单选项String[]menuText={"文件","编辑","常规滤镜","帮助","特殊滤镜","导航","工具"};//设置一个关于菜单选项的对象能直接调用的JMenu[]menu=new JMenu[menuText.length];for (int i=0;i< menuText.length;i++){JMenu jMenu=new JMenu(menuText[i]);menu[i]=jMenu;Dimension ds=new Dimension(110,30);jMenu.setPreferredSize(ds);jmu.add(jMenu);}//文件子菜单选项String[]name={"打开","保存","关闭"};for (int j=0;j< name.length;j++){JMenuItem jme=new JMenuItem(name[j]);Dimension ds=new Dimension(110,30);jme.setPreferredSize(ds);jme.addActionListener(ePixelMouse);menu[0].add(jme);}//编辑子菜单的选项String[]name1={"左旋转90度","右旋转90度","左旋转180度","右旋转180度"};for (int j=0;j< name1.length;j++){JMenuItem jme=new JMenuItem(name1[j]);Dimension ds=new Dimension(110,30);jme.setPreferredSize(ds);jme.addActionListener(ePixelMouse);menu[1].add(jme);}//滤镜子菜单的选项String[]name2={"原图","马赛克","灰度","油画","素描","珠纹"};for (int j=0;j< name2.length;j++){JMenuItem jme=new JMenuItem(name2[j]);Dimension ds=new Dimension(110,30);jme.setPreferredSize(ds);jme.addActionListener(ePixelMouse);menu[2].add(jme);}//特殊滤镜子菜单的选项String[]name3={"怀旧","梦幻","红外扫描","浮雕","特殊1","特殊2","卷积","合并"};for (int j=0;j< name3.length;j++){JMenuItem jme=new JMenuItem(name3[j]);Dimension ds=new Dimension(110,30);jme.setPreferredSize(ds);jme.addActionListener(ePixelMouse);menu[4].add(jme);}//帮助子菜单的选项JMenuItem jm1=new JMenuItem("撤回");Dimension dss=new Dimension(110,30);jm1.setPreferredSize(dss);jm1.addActionListener(ePixelMouse);menu[3].add(jm1);jf.setVisible(true);//从窗体获取画笔Graphics graphics=center.getGraphics();//画笔赋予ePixelMouse.g=graphics; // ePixelMouse.g= center.getGraphics();center.filterArr=ePixelMouse.filterArr;}public static void main(String[] args) {EDrawUI eDrawUI = new EDrawUI();eDrawUI.init();} }
2.需要的就是需要设置监听器的相关点击的作用,并获取到点击对象
public class EPixelMouse implements ActionListener {//定义画笔public Graphics g;//定义方点击按钮所获取得到的操作名称public String name;//设置存储滤镜效果的数组,设置为1000种效果public EPixelFilter[] filterArr = new EPixelFilter[1000];//操作数下标public int index = 0;//判断是否需要旋转的操作数public int flag=0;//当前滤镜效果public EPixelFilter ep;//鼠标监听器public void actionPerformed(ActionEvent e) {String name = e.getActionCommand();System.out.println("name:" + name);//加载图片(I/O)//图片路径String path = "C:\\qyl4.jpg";String path1 = "C:\\qyl3.jpg";//调用getImagePixel方法,把他存储的数据里面int[][] pixelArr = getImagePixel(path);//调用getImagePixel方法,把他存储的数据里面int[][] pixel1Arr = getImagePixel(path1);//将其绘制出来,通过点击的方法所获取的不同信息进行if (name.equals("原图")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("马赛克")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if(name.equals("灰度")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("油画")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("素描")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("浮雕")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("怀旧")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("梦幻")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("红外扫描")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("特殊1")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("特殊2")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("珠纹")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("合并")){ep = new EPixelFilter(pixelArr,pixel1Arr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("卷积")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);flag=1;//把滤镜效果保存在数组中filterArr[index++]=ep;}if (name.equals("左旋转90度")){ep = new EPixelFilter(pixelArr,name);ep.filter(g);//把滤镜效果保存在数组中filterArr[index++]=ep;}}//创造getImagePixel方法public int[][] getImagePixel(String path) {File file = new File(path);// ImageIO:对图片文件进行I/O// 获取缓冲图片BufferedImage buffImage = null;try {buffImage = ImageIO.read(file);} catch (IOException e1) {e1.printStackTrace();}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;} }
3.主要就是相关滤镜算法的编写,并对其封装调用
public class EPixelFilter {//保存当前图片数据的存储public int[][] pixelArr;public int[][] pixel1Arr;//通过name来识别滤镜效果public String name;//设置方法来传递滤镜效果的存储滤镜名称的参数public EPixelFilter(int[][] pixelArr, String name) {this.pixelArr = pixelArr;this.name = name;}public EPixelFilter(int[][] pixelArr,int[][] pixel1Arr, String name) {this.pixelArr = pixelArr;this.pixel1Arr=pixel1Arr;this.name = name;}//创造方法来点击调用,注意什么时候的值可以不同类别中互相传送public void filter(Graphics g) {System.out.println("name:" + name);if (name.equals("原图")) {drawY(g);}if (name.equals("马赛克")) {drawMSK(g);}if (name.equals("灰度")) {drawHH(g);}if (name.equals("油画")) {drawYH(g);}if (name.equals("素描")) {drawSM(g);}if (name.equals("浮雕")) {drawFD(g);}if (name.equals("怀旧")) {drawHJ(g);}if (name.equals("梦幻")) {drawMH(g);}if (name.equals("红外扫描")) {drawHW(g);}if (name.equals("特殊1")) {drawT1(g);}if (name.equals("特殊2")) {drawT2(g);}if (name.equals("珠纹")) {drawZW(g);}if (name.equals("卷积")) {drawJJ(g,pixelArr,kernel);}if (name.equals("合并")) {drawHB(g);}if (name.equals("左旋转90度")) {rotate(g);}}//创造不同点击所对应的作用,写出对应的算法//原图,首先创缓冲图片,Buffermage//开始写算法public void drawY(Graphics g) {// 创建缓冲图片:BufferedImageBufferedImage buff = new BufferedImage(pixelArr.length,pixelArr[0].length, BufferedImage.TYPE_INT_RGB);// 获取缓冲区画笔Graphics buffG = buff.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);// 把像素点画在缓冲图片上buffG.setColor(color);buffG.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(buff, 0, 0, null);}public void drawMSK(Graphics g) {// 创建缓冲图片:BufferedImageBufferedImage buff = new BufferedImage(pixelArr.length,pixelArr[0].length, BufferedImage.TYPE_INT_RGB);// 获取缓冲区画笔Graphics buffG = buff.getGraphics();for (int i = 0; i < pixelArr.length; i += 10) {for (int j = 0; j < pixelArr[0].length; j += 10) {// 像素值int pixel = pixelArr[i][j];// 把像素点画在缓冲图片上buffG.setColor(new Color(pixel));buffG.fillRect(i, j, 10, 10);}}// 把缓冲图片画在界面上g.drawImage(buff, 0, 0, null);}public void drawHH(Graphics g) {// 创建缓冲图片:BufferedImageBufferedImage buff = new BufferedImage(pixelArr.length,pixelArr[0].length, BufferedImage.TYPE_INT_RGB);// 获取缓冲区画笔Graphics buffG = buff.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);// 把像素点画在缓冲图片上buffG.setColor(pixelColor);buffG.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(buff, 0, 0, null);}public void drawYH(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔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(20) + 5;buffG.fillOval(i, j, r, r);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawSM(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = 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 < 180) {buff.setColor(Color.black);} else {buff.setColor(Color.WHITE);}buff.fillOval(i, j, 4, 4);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawFD(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < pixelArr.length; i++) {for (int j = 0; j < pixelArr[0].length; j++) {int pixel = pixelArr[i][j];pixel = (int) (pixel * 0.9848);Color color = new Color(pixel);buff.setColor(color);buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawHJ(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < pixelArr.length; i++) {for (int j = 0; j < pixelArr[0].length; j++) {int pixel = pixelArr[i][j];pixel = (int) (pixel * 0.99899);Color color = new Color(pixel);buff.setColor(color);buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawMH(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = 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);int b = color.getBlue();int a = color.getRed();int c = color.getGreen();Color color1 = new Color(b, a, c);buff.setColor(color1);buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawHW(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < pixelArr.length; i++) {for (int j = 0; j < pixelArr[0].length; j++) {int pixel = pixelArr[i][j];pixel = (int) (pixel * 0.95899);Color color = new Color(pixel);buff.setColor(color);buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawT1(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = 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);int b = color.getBlue();if (b > 200) {buff.setColor(Color.black);} else {pixel = (int) (pixel * 0.988);Color color1 = new Color(pixel);buff.setColor(color1);}buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawT2(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = 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);int b = color.getGreen();if (b > 200) {buff.setColor(Color.cyan);} else {Color color1 = new Color(50, 100, 150);buff.setColor(color1);}buff.drawLine(i, j, i, j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public void drawZW(Graphics g) {//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixelArr.length, pixelArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < pixelArr.length; i += 8) {for (int j = 0; j < pixelArr[0].length; j += 8) {int pixel = pixelArr[i][j];Color color = new Color(pixel);buff.setColor(color);buff.fillOval(i, j, 8, 8);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}float[][]kernel={{0,-1,0},{-1,1.99f,1},{0,-1,0}};float[][]kernel1={{0.8f,0,0.8f},{-1,1.8f,-1},{-1,0.8f,-1}};float[][]kernel2={{0,-1,0},{-1,4,-1},{0,-1,0}};float[][]kernel3={{-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1},{-1,-1,25,-1,-1},{-1,-1,-1,-1,-1},{-1,-1,-1,-1,-1}};public void drawJJ(Graphics g,int[][]pixelArr,float[][]kernel) {int[][] pixel=juanji(g, pixelArr, kernel);//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(pixel.length, pixel[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < pixel.length; i ++) {for (int j = 0; j < pixel[0].length; j ++) {int pix=pixel[i][j];Color color=new Color(pix,pix,pix);buff.setColor(color);buff.fillRect(i,j,1,1);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}public int[][]juanji(Graphics g,int[][]pixelArr,float[][]kernel){//保存卷积计算的数据大小与kernel大小一致int[][]tem=new int[kernel.length][kernel[0].length];int w= pixelArr[0].length-kernel[0].length+1;int h= pixelArr.length-kernel.length+1;//保存运算时候的有效数据,两个矩阵相乘,遍历卷积核int[][]juanji=new int[h][w];for (int i=0;i<h;i++){for (int j=0;j<w;j++){for (int m=0;m< kernel.length;m++){for (int n=0;n< kernel[0].length;n++){//把矩阵相乘后的值保存到tem数组当中tem[m][n]=(int) ((pixelArr[i+m][j+n])*(kernel[m][n]));}}//把tem数组中保存的数据进行相加int num=0;for (int y=0;y<kernel.length;y++){for (int z=0;z<kernel[0].length;z++){num+=tem[y][z];}}//把num限制在一个字节当中if (num<0)num=0;if (num>255)num=255;juanji[i][j]=num;}}return juanji;}public void drawHB(Graphics g){int w=Math.min(pixelArr.length, pixel1Arr.length);int h=Math.min(pixelArr[0].length,pixel1Arr[0].length);//创建缓冲图片BufferImageBufferedImage bufferedImage=new BufferedImage(w,h,BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff=bufferedImage.getGraphics();for (int i=0;i<w;i++){for (int j=0;j<h;j++){int pixel=pixelArr[i][j];int pixel1=pixel1Arr[i][j];Color color=new Color(pixel);Color color1=new Color(pixel1);int r=(int) (color.getRed()*0.5+color1.getRed()*0.5);int a=(int) (color.getGreen()*0.5+color1.getGreen()*0.5);int b=(int) (color.getBlue()*0.5+color1.getBlue()*0.5);Color color2=new Color(r,a,b);buff.setColor(color2);buff.drawLine(i,j,i,j);}}// 把缓冲图片画在界面上g.drawImage(bufferedImage, 0, 0, null);}//设置旋转方法 // public void rotate (Graphics g){ // 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]; // } // } // } // public void rotate (Graphics g){ // //创建缓冲图片BufferImage // BufferedImage bufferedImage=new BufferedImage(pixelArr.length,pixelArr[0].length,BufferedImage.TYPE_INT_BGR); // //获取缓冲区画笔 // Graphics buff=bufferedImage.getGraphics(); // int h= pixelArr.length; // int w=pixelArr[0].length; // int nh=w; // int nw=h; // int[][]newArr=new int[nh][nw]; // for (int i=0;i<nw;i++){ // for (int j=0;j<nh;j++){ // newArr[i][j]=pixelArr[h-j-1][i]; // } // }public void rotate (Graphics g){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];}}//创建缓冲图片BufferImageBufferedImage bufferedImage = new BufferedImage(newArr.length, newArr[0].length, BufferedImage.TYPE_INT_BGR);//获取缓冲区画笔Graphics buff = bufferedImage.getGraphics();for (int i = 0; i < newArr.length; i += 8) {for (int j = 0; j < newArr[0].length; j += 8) {int pixel = newArr[i][j];Color color = new Color(pixel);g.setColor(color);g.fillOval(i, j, 8, 8);}}} }
4.就是对面板类,以及图像滤镜的重绘效果展示
public class EMyPanel extends JPanel {public EPixelFilter[] filterArr=null;public EPixelFilter ep=null;//重写绘制面板的方法public void paint(Graphics g){// 1.绘制组件本身(调用父类中的paint方法)super.paint(g);System.out.println("绘制JPanel = "+ep);//2.绘制滤镜图像效果for (int i = 0; i < filterArr.length; i++){EPixelFilter filter=filterArr[i];if (filter != null) {// 还原当前的滤镜效果filter.filter(g);} elsebreak;}}
5.效果如图还是照常展示给大家(滤镜随机放了几个,然后有些,类似导航,工具,文件这些还未来得及添加)
6.有情况随时call我,欢迎随时交流
小浩浅谈如何为图片提供滤镜功能相关推荐
- 小浩浅谈之Java美颜相机pc端(视频)
在之前的文章中,给大家介绍了如果使用WebCamp来使用电脑的摄像头以及如何为图片添加各种滤镜,那么在这我们进行一个相互结合,就构成了一个我们pc端的美颜相机. 1.第一步和之前一样,就是框体 的创建 ...
- 小浩浅谈利用Java做一个视频运动追踪识别
寒假期间,一起做了一款pc端的美颜相机,在交流会期间,看到有的同学做了一些非常牛的功能添加,心血来潮,想整个视频运动追踪识别,在这和大家分析一下算法思路 1.原理很简单,就是在视频中的物体,就可以通过 ...
- 小浩浅谈Java三特性(封装,继承,多态)
1.封装,什么是封装,谈谈自己对封装的理解,封装就是将类的信息(比如说类的属性)隐藏在类的内部,不允许外部程序直接访问.此时就要提到一个关键字private,他是一个权限修饰符,可以用来修饰成员(变量 ...
- 小浩浅谈之在Java中摄像头的使用
在春节前夕,在陈哥的指导下,完成了美颜相机中一些滤镜效果的添加,但是之前滤镜效果的使用都是基于单独的图片,而我们的视频也是由一帧一帧的图片构成,所以我们在想完成美颜相机的情况下,首先要学会的是如何获取 ...
- 小浩浅谈 程序/进程/线程,并行/并发
1.程序,随着时代和社会的发展,我们开始学习各种各样的计算机语言,开始离不开编程,但是我们需要了解的是,什么是程序?程序代表什么?以及程序的作用?以及我们编程,编写程序是为了干嘛? 在这,我认为程序指 ...
- piv图像处理文献综述_浅谈photoshop对图片的处理 文献综述
浅谈 photoshop 对图片的处理 The Treatment to Discuss Photoshop Images 摘 要 : Photoshop :它是由 Adobe 公司开发的图形处理系列 ...
- php css定位到图片上,CSS_浅谈css中图片定位之所有图标放在一张图上,如今做网页为了使网站丰富多 - phpStudy...
浅谈css中图片定位之所有图标放在一张图上 如今做网页为了使网站丰富多彩,富于表现力,往往需要应用大量的图片/图标.如何处理这些图片,使其尽量不影响网页载入,解析等速度,是一个不大不小的问题.如果你的 ...
- 浅谈移动端图片压缩(iOS Android)
在 App 中,如果分享.发布.上传功能涉及到图片,必不可少会对图片进行一定程度的压缩.笔者最近在公司项目中恰好重构了双端(iOS&Android)的图片压缩模块.本文会非常基础的讲解一些图片 ...
- 浅谈移动端图片压缩(iOS Android)
在 App 中,如果分享.发布.上传功能涉及到图片,必不可少会对图片进行一定程度的压缩.笔者最近在公司项目中恰好重构了双端(iOS&Android)的图片压缩模块.本文会非常基础的讲解一些图片 ...
最新文章
- kotlin集合操作符——顺序操作符
- 读《不要告诉我你懂margin(海玉的博客)》有感
- IETF:名词历史简介互联网精神的典范
- C#中的where泛型约束中的new()使用(转)
- php array 如何访问,php – 如何访问$array [@key]值
- weblogic92 启动慢解决办法
- android 去掉顶部状态栏
- 算法 摩尔投票算法(图解例题)
- 总结开发Silverlight项目准则 [转]
- php 删除 session 文件,如何删除php中的session文件
- 有钱人也开始消费降级了!
- AI量化交易(一)——量化交易简介
- 哈希摘要、证书、对称密钥、公私密钥应用场景梳理
- win11怎么看激活状态
- oracle not in minus,Oracle Minus关键字 不包含...
- 路径和(cdq分治)
- LCD12864液晶显示屏与12位AD模块程序
- 使用MySQL可视化客户端,例如SQLyog,Navicat等,只编写SQL语句,使用2的N次方原理,快速初始化百万千万条数据
- 1079. 活字印刷
- [Yocto RM]11 - Features