java图片RGB转数组及特效处理

图片转数组

java中有drawLine的功能,当drawLine的起始点和终止点在同一点时,画出来的就是一个点,当你通过setColor的方法为其赋予颜色时,它画到屏幕上就是一个有颜色的像素点了,当你画出很多的点,便可以组成一幅图片了。获取图片数据的方法就是以二维数组的形式获取图片上点的RGB并保存起来,当你要画的时候,只要遍历数组然后取出颜色画到屏幕上即可。所以,如果我们要处理图片,并为其加上一些特殊效果,首先就要把它转化为一个二维数组。

	public static int[][] img2color(String imgfile) {
		File file = new File(imgfile);
		BufferedImage bi = null;
		try {
			bi = ImageIO.read(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		int width = bi.getWidth();
		int height = bi.getHeight();
		int minx = bi.getMinX();
		int miny = bi.getMinY();
		int[][] allcolor = new int[height - miny][width - minx];
		for (int j = miny; j < height; j++) {
			for (int i = minx; i < width; i++) {
				int pixel = bi.getRGB(i, j);// 将一个数字转换为RGB数字
				allcolor[j - miny][i - minx] = pixel;
			}
		}		
		return allcolor;
	}
	public static Color[][] img3color(String imgfile){  
        File file = new File(imgfile);  
        BufferedImage bi = null;  
        try {  
            bi = ImageIO.read(file);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  

        int width = bi.getWidth();  
        int height = bi.getHeight();  
        int minx = bi.getMinX();  
        int miny = bi.getMinY();  
        Color[][] allcolor=new Color[height-miny][width-minx];
        for (int j = miny; j < height; j++) { 
            for (int i = minx; i < width; i++) {  
                int pixel = bi.getRGB(i, j); // 将一个数字转换为RGB数字  
                allcolor[j-miny][i-minx] = new Color(pixel); 
            }
        }  
        return allcolor;
    }

这里有两种方法可以选择,第一种方法是把每一个像素点的转化为一个用int表示的参数,它的好处是可以通过对参数做一些判断,获得一些条件的限定然后为画笔的RGB参数赋值,实现类似黑白化的效果。第二种方法是获取Color值,存入数组,调用时可直接为画笔颜色赋值。

图片黑白二值化

数组中存的是一个int值参数,使用时需要先试着输出数组的值,判断它的大致范围,然后在其中选择一个合适的值来做判断。我们这里是t大于10599121把像素点赋为黑色,其余不画。

		if ("黑白".equals(e.getActionCommand()))
		{
			g.setColor(Color.white);
			g.fillRect(0, 0, 1500, 1000);
			System.out.println("黑白");
			int[][] allcolor = img2color("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
			for (int i=0;i<allcolor.length;i++) 
			{
				for (int j=0;j<allcolor[i].length;j++)
				{
					int t=-allcolor[i][j];
					if(t>10599121)
					{
					Color c= new Color(0,0,0);
					g.setColor(c);
					g.drawLine(j+300,i+150, j+300, i+150);
					}
				}
			}
		} 

在这里插入图片描述

图片添加马赛克

马赛克的实现思路就是把画面的像素点数量减少,降低画面的分辨率。我们隔10个点取一色,然后fill这10*10的区域,这样就形成马赛克的方块了,我们可以根据取样的间隔来调整画面的可辨识度。

		else if ("马赛克".equals(e.getActionCommand()))
		{
			g.setColor(Color.white);
			g.fillRect(0, 0, 1500, 1000);
			System.out.println("马赛克");
			Color[][] allcolor=img3color("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
			for (int i=0;i<allcolor.length;i=i+10) 
			{
				for (int j=0;j<allcolor[i].length;j=j+10)
				{
	                //System.out.println(color);
					Color c=allcolor[i][j];
					g.setColor(c);
	                g.fillRect(j+300,i+150, 10, 10);
	            }
	        }
		}

在这里插入图片描述

图片波纹化

这里用到了一个sin函数,这里我们要注意参数的类型,int会被取整为0,另外还要注意函数的放大,不然效果会不明显哦。

		else if ("波纹化".equals(e.getActionCommand()))
		{
			g.setColor(Color.white);
			g.fillRect(0, 0, 1500, 1000);
			System.out.println("波纹化");
			Color[][] allcolor=img3color("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
			for (int i=0;i<allcolor.length;i++) 
			{
				for (int j=0;j<allcolor[i].length;j++)
				{
					Color c=allcolor[i][j];
					g.setColor(c);
					int y=(int)(12*Math.sin((double)j/10));
					g.drawLine(j+300,i+150-y, j+300, i+150-y);
	            }
	        }
		} 	

在这里插入图片描述

单色调处理

这里我们贴上把图片转为蓝色调的代码。红色,绿色等处理方法都同理,核心就是对RGB参数的赋值。

		else if ("蓝色".equals(e.getActionCommand())) 
		{
            g.setColor(Color.white);
			g.fillRect(0, 0, 1500, 1000);
			System.out.println("蓝色");
			int[][] allcolor = img2color("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
			for (int i=0;i<allcolor.length;i++) 
			{
				for (int j=0;j<allcolor[i].length;j++)
				{
					int t=-allcolor[i][j];
					Color c= new Color(0,0,t/100000);
					g.setColor(c);
					g.drawLine(j+300,i+150, j+300, i+150);			
				}
			}
		}

在这里插入图片描述

图片的分散和聚合

这里的效果是,当按下“分散”按钮时,让图片化为许多的碎片向四周散落,再按下“恢复”按钮时,图片又重新聚拢恢复成原来的样子,这段代码思路我的总结就是:让图片化为若干独立的有自己属性的对象,记录初始坐标,在线程内修改坐标让他们运动,聚拢时即寻找每个小图片的x0和y0(初始坐标)。
监听器类:

    public class Listener implements ActionListener  {
	private Graphics g;
    private ArrayList<Picture> array = new ArrayList<Picture>();
	private PictureJpanel cp;
	private ThreadPicture tp;
	public int flag=0;
	private Listener listener;
	public void setg(Graphics g) {
		this.g = g;
	}	 
	 public void actionPerformed(ActionEvent e)
    {
		 if ("分散".equals(e.getActionCommand())) 
		{
			flag=1;
			g.setColor(Color.white);
			g.fillRect(0, 0, 1500, 1000);
			System.out.println("分散");
			Color[][] allcolor=img3color("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
			for (int i=0;i<allcolor.length;i++) 
			{
				for (int j=0;j<allcolor[i].length;j++)
				{
					Color c=allcolor[i][j];
					g.setColor(c);					
					g.drawLine(j+300,i+150, j+300, i+150);
	            }
	        }
			for (int i=0;i<allcolor.length;i=i+50) 
			{
				for (int j=0;j<allcolor[i].length;j=j+50)
				{
					File file = new File("E:\\workspace\\mayifan\\src\\com\\myf\\ps1110\\图片\\1.jpg");
					BufferedImage bi = null;
					try {
						bi = ImageIO.read(file);
					} catch (Exception e1) {
						e1.printStackTrace();
					}
					Color[][] allcolor1=new Color[50][50];
					for (int n = i; n < i+50; n++)
					{
						for (int m = j; m < j+50; m++)
						{
							int pixel = bi.getRGB(m, n);// 下面三行代码将一个数字转换为RGB数字
							allcolor1[n-i][m-j] = new Color(pixel);		
						}
					}
					int rand=(int)(1+Math.random()*(4-1+1));
					Picture pic= new Picture(j+300,i+150,50,50,allcolor1,j+300,i+150,rand);
					array.add(pic);	
					//System.out.println(array.size());
	            }
	        }
			if(tp==null)
			{
			ThreadPicture tp= new ThreadPicture();
			tp.start();
			tp.setcp(cp);
			tp.setArray(array);
			tp.setlistener(listener);
			}	
		}
		else if ("恢复".equals(e.getActionCommand())) 
		{
		    System.out.println("恢复");
			flag=2;		
		}		
    }
	public static Color[][] img3color(String imgfile){  
        File file = new File(imgfile);  
        BufferedImage bi = null;  
        try {  
            bi = ImageIO.read(file);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        int width = bi.getWidth();  
        int height = bi.getHeight();  
        int minx = bi.getMinX();  
        int miny = bi.getMinY();  
        Color[][] allcolor=new Color[height-miny][width-minx];
        for (int j = miny; j < height; j++) { 
            for (int i = minx; i < width; i++) {  
                int pixel = bi.getRGB(i, j); ///将一个数字转换为RGB数字  
                allcolor[j-miny][i-minx] = new Color(pixel); 
            }
        }  
        return allcolor;
    }
	public void setcp(PictureJpanel cp) {
		// TODO Auto-generated method stub
		this.cp=cp;
		cp.setarray(array);
	}
	public void setlistener(Listener listener) {
		// TODO Auto-generated method stub
		this.listener=listener;
	}  
}

图片类:

public class Picture {
     public int x0;
     public int y0;
     public int height;
     public int width;
     public Color[][] allcolor=new Color[height][width];
	 public int x;
	 public int y;
     public int direct;
	 public Picture(int x0,int y0,int height, int width, Color[][] allcolor, int x,int y , int direct)
	 {
		 this.x0=x0;
		 this.y0=y0;
		 this.height=height;
		 this.width=width;
		 this.allcolor=allcolor;
		 this.x=x;
		 this.y=y;
		 this.direct=direct;
	 }

画板重绘:

public class PictureJpanel extends JPanel{		
	private ArrayList<Picture> array;
	public void paint(Graphics g)
	{
		super.paint(g);
		for(int i=0;i<array.size();i++)
		{
			Picture pic= array.get(i);
			for (int k=0;k<50;k++) 
			{
				for (int j=0;j<50;j++)
				{
					Color c=pic.allcolor[k][j];
					g.setColor(c);
					g.drawLine(pic.x+j,pic.y+k,pic.x+j,pic.y+k);			
				}
			}												
		}										
	}
	public void setarray(ArrayList<Picture> array) {
		// TODO Auto-generated method stub
		this.array=array;
	}					
}

图片线程:

public class ThreadPicture extends Thread {          	
	private PictureJpanel cp;
	private ArrayList<Picture> array;
	private Listener listener;
	public void run(){		     
		while(true){			
			for(int i=0;i<array.size();i++)
			{
				int randx =(int)(1+Math.random()*(2-1+1));
				Picture pic= array.get(i);
				if(listener.flag==2&&Math.abs(pic.x-pic.x0)<5)
				{
					pic.x=pic.x0;	
					continue;
				}				
				if(listener.flag==1)
				{
						switch(pic.direct)
						{
						case 1:
						pic.x+=randx;
						break;
						case 2:
						pic.x-=randx;
						break;
						case 3:
						pic.x+=randx;
						break;
						case 4:
						pic.x-=randx;
						break;
						}
				}
				else if(listener.flag==2)
				{
						switch(pic.direct)
						{
						case 1:
						pic.x-=randx;
						break;
						case 2:
						pic.x+=randx;
						break;
						case 3:
						pic.x-=randx;
						break;
						case 4:
						pic.x+=randx;
						break;
					}
				}
				//System.out.println(pic.x);
			}
			for(int i=0;i<array.size();i++)
			{
				int randy =(int)(1+Math.random()*(2-1+1));
				Picture pic= array.get(i);
				if(listener.flag==2&&Math.abs(pic.y-pic.y0)<5)
				{
					pic.y=pic.y0;	
					continue;
				}				
				if(listener.flag==1)
				{
						switch(pic.direct)
						{
						case 1:
						pic.y+=randy;
						break;
						case 2:
						pic.y-=randy;
						break;
						case 3:
						pic.y-=randy;
						break;
						case 4:
						pic.y+=randy;
						break;
						}
				}
				else if(listener.flag==2)
				{
						switch(pic.direct)
						{
						case 1:
						pic.y-=randy;
						break;
						case 2:
						pic.y+=randy;
						break;
						case 3:
						pic.y+=randy;
						break;
						case 4:
						pic.y-=randy;
						break;
					}
				}
				//System.out.println(pic.x);
			}			
			cp.repaint();			
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}												
		}		    		 		
	}
	public void setcp(PictureJpanel cp) {
		// TODO Auto-generated method stub
		this.cp=cp;
	}
	public void setArray(ArrayList<Picture> array) {
		// TODO Auto-generated method stub
		this.array=array;
	}
	public void setlistener(Listener listener) {
		// TODO Auto-generated method stub
		this.listener=listener;
	}		
}

在这里插入图片描述

基于以上思路我们还可以对图像做很多处理,加各种有趣的特效!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值