Java图片处理


本文介绍一个简单的图片处理界面的实现

1、前端界面制作

首先创建窗体对象

		JFrame jf=new JFrame();
		jf.setSize(640,500);
		jf.setTitle("美颜相机");
		jf.setLocationRelativeTo(null);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//设置尺寸、标题、位置、退出

在窗体上给菜单图片显示区域分别创建一块面板容器JPanel

		//设置菜单区域
	    JPanel jmenu=new JPanel();
	    jme.setBackground(Color.BLACK);  
	    jf.add(jmenu,BorderLayout.CENTER); 
	    //设置图片区域
 		JPanel jiamge = new JPanel();
 		jiamge.setBackground(jf.getBackground());
 		jf.add(jimage,BorderLayout.NORTH);

使用Menu(菜单)设计界面,创建窗体对象上的菜单条,菜单条上的菜单由三部分构成:
javax.swing.JMenuBar类:放置菜单的菜单条
javax.swing.JMenu类:菜单目录对象,例子中的文件、编辑
javax.swing.JMenuItem:菜单条目录,例子中的新建、打开、原图等
步骤为 1、创建菜单条对象
2、创建菜单目录,把菜单目录添加到菜单条上
3、创建菜单条目,并添加到菜单目录上,给每个菜单条目添加动作监听器

		JMenuBar Mb=new JMenuBar();
		jimage.add(Mb,BorderLayout.EAST);
 		String[] menu= {"文件","编辑"};
 		String[][] item= {{"新建","打开","退出"},{"原图","灰度","马赛克","马克笔","模糊","特征提取"}};
 		for(int i=0;i<menu.length;i++) {
 			JMenu me=new JMenu(menu[i]);
 			Mb.add(me);
 			for(int j=0;j<item[i].length;j++) {
 				JMenuItem mi=new JMenuItem(item[i][j]);
 				me.add(mi);
 				mi.addActionListener(listener);
 			}
 		}	

设置组件的可见

	jf.setVisible(true);

给图片显示区域添加画笔

	jf.setVisible(true);
	Graphics g=jmenu.getGraphics();

界面设计结构如下图
在这里插入图片描述

2、文件选择器

针对菜单–文件–选择添加动作监听器,使之能够打开文件选择窗口

 			  JFileChooser chooser = new JFileChooser();
			  chooser.showOpenDialog(null);//打开文件选择窗口
			  File file=chooser.getSelectedFile();//获取选择的文件
			  String path=chooser.getSelectedFile().getPath());//获取文件路径

3、把图片保存为数组

彩色图片在计算机中以二维数组的形式存在,其颜色由RGB三原色配制而成,彩色图片的每个点的数据信息包括它的位置以及RGB值。对图片进行处理的方式,即改变数组。

			//通过函数把指定路径的图片保存为数组
			public int[][]getIamgePixel(String path) {
			//保存指定路径的图片
			File file = new File(path);
			//新建缓冲区对象
			BufferedImage bfi = null;
			try {
			//读取图片到缓冲区
				bfi = ImageIO.read(file);
			} catch (IOException e) {
				e.printStackTrace();
			}
			//根据图片大小建立二维数组
			int width=bfi.getWidth();
			int height=bfi.getHeight();
			int arr[][]=new int[width][height];
			for (int i=0;i<width;i++) {
				for (int j=0;j<height;j++) {
				//把像素点的RGB值保存到数组的对应位置
					int pixel=bfi.getRGB(i, j);
					arr[i][j]=pixel;
				}
			}
			return arr;
		}

4、把数组输出为图片

一种方法:建立缓冲区,把二维数组的RGB值设置为缓冲区的画笔的颜色,最后显示缓冲区即可

public void drawPixel(int[][] arrPixel){
		BufferedImage buffImage = new BufferedImage(arrPixel.length, arrPixel[0].length, 
				BufferedImage.TYPE_INT_RGB); 
		//把像素画在缓冲区上(获取缓冲区画笔)
		Graphics buffG = buffImage.getGraphics();
		//遍历出arrPixel像素值,绘制像素点
		for(int i=0;i<arrPixel.length;i++){
			for(int j=0;j<arrPixel[i].length;j++){
				int pixel = arrPixel[i][j];
				Color color = new Color(pixel);
//				Color newColor = new Color(newPixel,newPixel,newPixel);
				buffG.setColor(color);
				
				//设置像素值
//				buffImage.setRGB(i, j,newColor.getRGB());
				
				//绘制像素点:jvm>os>显卡>屏幕
				buffG.fillRect(i, j, 1, 1);
			}
		}
		//显示缓冲区
		g.drawImage(buffImage, 80, 80, null);
	}

另一种方法:不使用缓冲区,直接在画布上画点。

			public void drawPixel(int[][] arr){	
			for(int i=0;i<arr.length;i++) {
				for(int j=0;j<arr[0].length;j++) {
				Color color =new Color(arr[i][j]);			
				g.setColor(color);
				g.drawLine(i,j,i,j);
				}
			}

5、灰度处理

灰色的R、G、B三个值相近,随着RGB值的增加,颜色逐渐从浅灰色变成深灰色,因此可以取RGB三个值的平均值作为新的R、G、B值。

public void drawgrey(int [][]arrPixel) {
		BufferedImage buffImage = new BufferedImage(arrPixel.length, arrPixel[0].length, 
				BufferedImage.TYPE_INT_RGB); 
		Graphics buffG = buffImage.getGraphics();
		for(int i=0;i<arrPixel.length;i++){
			for(int j=0;j<arrPixel[i].length;j++){
				int pixel = arrPixel[i][j];
				Color color = new Color(pixel);
				
				int grey=(color.getRed()+color.getGreen()+color.getBlue())/3;
				Color newColor = new Color(grey,grey,grey);
				
				buffG.setColor(color);				
				buffImage.setRGB(i, j,newColor.getRGB());
				//绘制像素点:jvm>os>显卡>屏幕
//				buffG.fillRect(i, j, 1, 1);
			}
		}
		gr.drawImage(buffImage, 0, 0, null);
	}

6、马赛克处理

马赛克的一种方式是让一定区域的像素点都设置为相同的颜色。
所以可以每隔10个像素点设置一种颜色。

public void drawmisake(int [][]arrPixel) {
			BufferedImage buffImage = new BufferedImage(arrPixel.length, arrPixel[0].length, 
					BufferedImage.TYPE_INT_RGB); 
			Graphics buffG = buffImage.getGraphics();
			for(int i=0;i<arrPixel.length;i=i+10){
				for(int j=0;j<arrPixel[i].length;j=j+10){
					int pixel = arrPixel[i][j];
					Color color = new Color(pixel);
					buffG.setColor(color);				
					buffG.fillRect(i, j, 10, 10);
				}
			}
			gr.drawImage(buffImage, 0, 0, null);
		}

7、马克笔

马克笔即通过鼠标绘制出想要的线条,通过调用MouseMotionListener中的MouseDragged()方法来实现。

public void mouseDragged(MouseEvent e){
    	System.out.println("拖动");
    	if(BottomName=="马克笔") {
    		System.out.println("dianji");
    		int x=e.getX();
    		int y=e.getY();
    		g.setColor(Color.red);
    		g.drawOval(x-4, y-4,8, 8);	
    	}
    }

8、模糊处理

模糊处理,将原图片的像素点的颜色重新设置,比较常用的方法有把中间像素点的RGB值和周围像素点的RGB值进行加权平均,得到新的中间像素点党的RGB值。

		public void drawmisake(int [][]arrPixel) {
			for(int i=1;i<arr_width-2;i++) {
				for(int j=1;j<arr_length-2;j++) {
					r1_value[i][j]=(int)(0.094*r_value[i-1][j-1]+0.118*r_value[i][j-1]+0.094*r_value[i+1][j-1]+0.118*r_value[i-1][j]+0.147*r_value[i][j]+0.118*r_value[i+1][j]+0.094*r_value[i-1][j+1]+0.118*r_value[i][j+1]+0.094*r_value[i+1][j+1]);
					g1_value[i][j]=(int)(0.094*g_value[i-1][j-1]+0.118*g_value[i][j-1]+0.094*g_value[i+1][j-1]+0.118*g_value[i-1][j]+0.147*g_value[i][j]+0.118*g_value[i+1][j]+0.094*g_value[i-1][j+1]+0.118*g_value[i][j+1]+0.094*g_value[i+1][j+1]);
					b1_value[i][j]=(int)(0.094*b_value[i-1][j-1]+0.118*b_value[i][j-1]+0.094*b_value[i+1][j-1]+0.118*b_value[i-1][j]+0.147*b_value[i][j]+0.118*b_value[i+1][j]+0.094*b_value[i-1][j+1]+0.118*b_value[i][j+1]+0.094*b_value[i+1][j+1]);
					Color color =new Color(r1_value[i][j],g1_value[i][j],b1_value[i][j]);			
					g.setColor(color);
					g.drawLine(80+i,80+j,80+i,80+j);
				}
			}
		}

9、特征提取

//float filter[][]= {{0.8f,0,0.8f},{-1,1.8f,-1},{-1,0.8f,-1}};
		float filter[][]= {{0,-1,0},{-1,4,-1},{0,-1,0}};
		int temr[][]= new int[3][3];
		int temg[][]= new int[3][3];
		int temb[][]= new int[3][3];
		for(int i=0;i<178;i++) {
			for(int j=0;j<178;j++) {
				for(int y=0;y<3;y++) {
					for(int z=0;z<3;z++) {
					temr[y][z]=(int)(r_value[i+y][j+z]*filter[y][z]);	
					temg[y][z]=(int)(g_value[i+y][j+z]*filter[y][z]);	
					temb[y][z]=(int)(b_value[i+y][j+z]*filter[y][z]);	
					}
				}
				int rgb[]= {0,0,0};
				for(int m=0;m<3;m++) {
					for(int y=0;y<3;y++) {
						for(int z=0;z<3;z++) {
							rgb[m]+=temr[y][z];		
						}
					}
					if(rgb[m]<0)rgb[m]=0;
				if(rgb[m]>255)rgb[m]=255;
				}
				r1_value[i][j]=rgb[0];
				g1_value[i][j]=rgb[1];
				b1_value[i][j]=rgb[2];	
			}
		}
		for(int i1=0;i1<arr_width-2;i1++) {
			for(int j=0;j<arr_length-2;j++) {
				Color color =new Color(r1_value[i1][j],g1_value[i1][j],b1_value[i1][j]);			
				g.setColor(color);
				g.drawLine(80+i1,80+j,80+i1,80+j);
			}
		}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值