代码展示

ImageEFF

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class ImageEFF {
	
	public int[][] ImageToArray(String imgpath){
		File imgfile=new File(imgpath);
		BufferedImage img=null;
		try {
			img=ImageIO.read(imgfile);
		}catch(java.io.IOException e) {
			e.printStackTrace();
			System.err.println("图像读取失败");
		}
		int w=img.getWidth();
		int h=img.getHeight();
		int [][] imgArr=new int [w][h];
		for(int i=0;i<w;i++) {
			for(int j=0;j<h;j++) {
				imgArr[i][j]=img.getRGB(i, j);
			}
			
		}
		
		return imgArr;
		
	}
	
	//油画融合
	
	public BufferedImage drawImagenmd(int [][]imgArr1,int [][]imgArr2,Graphics g) {      //用返回值保存
		BufferedImage buffimg=new BufferedImage(imgArr1.length,imgArr1[0].length,BufferedImage.TYPE_INT_ARGB);
		//TYPE_INT_ARGB代表颜色为int(4个字节),红色通道道在16-23,绿色在8-15和蓝色在0-7
		
		// 将所有的像素值存入缓冲图片- 操作- 内存操作
		for(int i=0;i<imgArr1.length;i++) {
			for(int j=0;j<imgArr1[i].length;j++) {
				int value=imgArr1[i][j];
				//Color color=new Color(value);
				//g.setColor(color);//相当于在重绘每个像素点 所以要给画笔每个像素的颜色再填充
				//g.fillRect(50+i, 50+j, 1, 1);
				int value1=imgArr2[i][j];
				buffimg.setRGB(i, j, (value+value1)/2);//全部初始化缓冲在内存的BufferedImage中 还未画
			}
		}
		//将整张图片一次性绘制
		g.drawImage(buffimg, 0,0,null);
		
		return buffimg;
	}
	
	//马赛克瓷砖
	
	public BufferedImage drawImage0(int [][]imgArr,Graphics g) {
		BufferedImage buffimg=new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
		Graphics buffg=buffimg.getGraphics();
		for(int i=0;i<imgArr.length;i+=10) {
			for(int j=0;j<imgArr[i].length;j+=10) {
				int value=imgArr[i][j];
				Color color=new Color(value);
				buffg.setColor(color);//相当于在重绘每个像素点 所以要给画笔每个像素的颜色再填充
				buffg.fillRect(i, j, 8, 8);
			}
		}
		g.drawImage(buffimg, 0, 0, null);
		return buffimg;
	}
	
	
	  /**
     * 灰度
     * @param path  图片路径
     * @param g 图形类 功能 绘制像素点
     */

	public BufferedImage drawImage1(int [][]imgArr,Graphics g) {
		BufferedImage buffimg=new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
		Graphics buffg=buffimg.getGraphics();
		for (int i=0;i<imgArr.length;i++) {
			for(int j=0;j<imgArr[i].length;j++) {
				int value=imgArr[i][j];
				int red=(value>>16)&0xFF;
				int green=(value>>8)&0xFF;
				int blue=(value>>0)&0xFF;
				int gray=(int)(red*0.6+green*0.3+blue*0.1);
				Color color=new Color(gray,gray,gray);
				buffg.setColor(color);
				buffg.fillRect(i, j, 1, 1);
				
			}
		}
		g.drawImage(buffimg, 0, 0, null);
		return buffimg;
	}
	
	 /**
     * 二值化的手绘效果
     * @param path  图片路径
     * @param g 图形类 功能 绘制像素点
     */

	public BufferedImage drawImage2(int [][]imgArr,Graphics g) {
		BufferedImage buffimg = new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
		Graphics buffg=buffimg.getGraphics();
		for(int i=0;i<imgArr.length;i++) {
			for(int j=0;j<imgArr[i].length;j++) {
				int value=imgArr[i][j];
				int red=(value>>16)&0xFF;
				int green=(value>>8)&0xFF;
				int blue=(value>>0)&0xFF;
				int gray=(int)(red*0.4+green*0.3+blue*0.3);
				if(gray<127) {
				    buffg.setColor(Color.BLACK);
				}else {
					buffg.setColor(Color.white);
				}
				buffg.fillRect(i, j, 1, 1);
			}
		}
		g.drawImage(buffimg, 0, 0, null);
		return buffimg;
	}
	
	 /**
     * 轮廓检测
     *  相邻之间的像素颜色进行比较
     * @param path  图片路径
     * @param g 图形类 功能 绘制像素点
     */

	public BufferedImage drawImage3(int [][]imgArr,Graphics g) {
		BufferedImage buffimg = new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
		Graphics buffg=buffimg.getGraphics();
		for(int i=0;i<imgArr.length-2;i++) {
			for(int j=0;j<imgArr[i].length-2;j++) {//注意减2
				int value=imgArr[i][j];
				int red=(value>>16)&0xFF;
				int green=(value>>8)&0xFF;
				int blue=(value>>0)&0xFF;
				int gray=(int)(red*0.4+green*0.3+blue*0.3);
				
				int valueN=imgArr[i+2][j+2];
				int redN=(valueN>>16)&0xFF;
				int greenN=(value>>8)&0xFF;
				int blueN=(value>>0)&0xFF;
				int grayN=(int)(redN*0.4+greenN*0.3+blueN*0.3);
				
				if(Math.abs(gray-grayN)>15) {//Math.abs绝对值
					buffg.setColor(Color.red);
				}else {
					buffg.setColor(Color.white);
				}
				buffg.fillRect(i, j, 1, 1);
			}
		}
		g.drawImage(buffimg, 0, 0, null);
		return buffimg;
	}
	
	//马赛克
	
		public BufferedImage drawImage5(int [][]imgArr,Graphics g) {
	
			BufferedImage buffimg=new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
			Graphics buffg=buffimg.getGraphics();   //直接画在缓冲区 不到GPU 是内存操作
			for(int i=0;i<imgArr.length;i+=10) {
				for(int j=0;j<imgArr[i].length;j+=10) {
					int value=imgArr[i][j];
					Color color=new Color(value);
					buffg.setColor(color);//相当于在重绘每个像素点 所以要给画笔每个像素的颜色再填充
					buffg.fillRect(i, j, 10, 10);//坐标以从50往后移 drawImage中坐标不用为0就好
				}
			}
			g.drawImage(buffimg, 0, 0, null);//将buffimg内存缓冲区中的取出一次性绘制
			return buffimg;
		}
		//原图缩小
		public void drawImage6(int [][]imgArr,Graphics g) {
			BufferedImage buffimg=new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB);
			//TYPE_INT_ARGB代表颜色为int(4个字节),红色通道道在16-23,绿色在8-15和蓝色在0-7
			
			// 将所有的像素值存入缓冲图片- 操作- 内存操作
			for(int i=0;i<imgArr.length;i++) {
				for(int j=0;j<imgArr[i].length;j++) {
					int value=imgArr[i][j];
					//Color color=new Color(value);
					//g.setColor(color);//相当于在重绘每个像素点 所以要给画笔每个像素的颜色再填充
					//g.fillRect(50+i, 50+j, 1, 1);
					
					buffimg.setRGB(i, j, value);//全部初始化缓冲在内存的BufferedImage中 还未画
				}
			}
			//将整张图片一次性绘制
			g.drawImage(buffimg, 50,50,200,200,null);//通过200 200 缩小
		}
		
		
		//原图
		public BufferedImage drawImagelaozi(int [][]imgArr,Graphics g) {      //用返回值保存
			BufferedImage buffimg=new BufferedImage(imgArr.length,imgArr[0].length,BufferedImage.TYPE_INT_ARGB);
			//TYPE_INT_ARGB代表颜色为int(4个字节),红色通道道在16-23,绿色在8-15和蓝色在0-7
			
			// 将所有的像素值存入缓冲图片- 操作- 内存操作
			for(int i=0;i<imgArr.length;i++) {
				for(int j=0;j<imgArr[i].length;j++) {
					int value=imgArr[i][j];
					//Color color=new Color(value);
					//g.setColor(color);//相当于在重绘每个像素点 所以要给画笔每个像素的颜色再填充
					//g.fillRect(50+i, 50+j, 1, 1);
					
					buffimg.setRGB(i, j, value);//全部初始化缓冲在内存的BufferedImage中 还未画
				}
			}
			//将整张图片一次性绘制
			g.drawImage(buffimg, 0,0,null);
			
			return buffimg;
		}

}

ImageListene

import java.awt.*;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Stack;

public class ImageListener extends ListenerUtils {
	public Graphics g;
	JPanel jp;
	String path="F:\\自己填\\作业\\1.png";
	String path1="F:\\自己填\\作业\\2.jpg";
	String path2="F:\\自己填\\作业\\3.jpg";
	public String btnstrs;
	BufferedImage [] buffimgs=new BufferedImage[100];//存返回值对象的数组
	Stack<BufferedImage> buffstack= new Stack<BufferedImage>(); 
	int index=0;//计数器
	int indexmsk=0;
	int x1,y1,x2,y2;
	int x3,y3;
	
	//  1)构造出来一个类的实例 (2)对构造出来个一个类的实例(对象)初始化
	//构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有
	int[][] imgArr;
	int[][] imgArr1;
	int[][] imgArr2;
	ImageEFF imgeff;
	//类构造方法
	//就是类构造对象时调用的方法,主要用来实例化对象。
	ImageListener(){          
		imgeff = new ImageEFF();
		imgArr=imgeff.ImageToArray(path);
		imgArr1=imgeff.ImageToArray(path1);
		imgArr2=imgeff.ImageToArray(path2);
	}
	
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		btnstrs =e.getActionCommand();
		if(btnstrs.equals("原图")) {
			BufferedImage img=imgeff.drawImagelaozi(imgArr, g);//img 存返回值对象(内存缓冲池中已画好的内容)
			buffimgs[index++]=img;
			indexmsk++;
			System.out.println("index"+index);
		}
		else if(btnstrs.equals("马赛克")) {
			BufferedImage img=imgeff.drawImage5(imgArr, g);
			buffimgs[index++]=img;
			indexmsk++;
			System.out.println("index"+index);
		}
		else if(btnstrs.equals("马赛克瓷砖")) {
			BufferedImage img=imgeff.drawImage0(imgArr, g);
			buffimgs[index++]=img;
			indexmsk++;
			buffstack.push(img);
		}
		else if(btnstrs.equals("灰度")) {
			BufferedImage img=imgeff.drawImage1(imgArr, g);
			buffimgs[index++]=img;
			indexmsk++;
			System.out.println("index"+index);
		}
		else if(btnstrs.equals("轮廓检测")) {
			BufferedImage img=imgeff.drawImage3(imgArr, g);
			buffimgs[index++]=img;	
			indexmsk++;
			buffstack.push(img);
			}
		else if(btnstrs.equals("二值化")) {
			BufferedImage img=imgeff.drawImage2(imgArr, g);
			buffimgs[index++]=img;
			indexmsk++;
			buffstack.push(img);
		}
		else if(btnstrs.equals("缩小")) {
			//取当前图片
			BufferedImage buffimg=buffimgs[indexmsk-1];
			//创建一个新的空缓冲区
			BufferedImage buffimg1=new BufferedImage(buffimg.getWidth(), buffimg.getHeight(), BufferedImage.TYPE_INT_ARGB);
			Graphics buffg=buffimg1.getGraphics();
			for(int i=0;i<buffimg.getWidth();i++) {
				for(int j=0;j<buffimg.getHeight();j++) {
					int rgbvalue=buffimg.getRGB(i,j);
					Color color=new Color(rgbvalue);
					buffimg1.setRGB(i, j, rgbvalue);

				}
			}
			g.drawImage(buffimg, 0,0,200,200,null);
			
			buffimgs[index++]=buffimg1;
			indexmsk++;
		}
		else if(btnstrs.equals("撤回")) {

			if(index==0) 
			{
				 return;
			}
			else 
			{
			 // 删除数据 
			 buffimgs[index-1]=null;
			 index--;
			 
			}
		    
			 jp.repaint();//调用repaint 就相当于在调用jp的paint方法
		}
		else if(btnstrs.equals("油画融合")) {
			BufferedImage img=imgeff.drawImagenmd(imgArr1,imgArr2, g);
			buffimgs[index++]=img;
			indexmsk++;
		}

		
		
	}
	
	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		super.mousePressed(e);
		if(btnstrs.equals("选择截屏区域")) {
			x1=e.getX();
			y1=e.getY();
		}
	}
	
	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		super.mouseReleased(e);
		if(btnstrs.equals("选择截屏区域")) {
			x2=e.getX();
			y2=e.getY();
		}
	}
	
	@Override
	public void mouseDragged(MouseEvent e) {
		// 鼠标拖动 局部马赛克
		System.out.println("拖动");
		int oldx=0;
		int oldy=0;
		if("局部马赛克".equals(btnstrs)) {
			
		
		//取当前图片
		BufferedImage buffimg=buffimgs[indexmsk-1];
		//创建一个新的空缓冲区
		BufferedImage buffimg1=new BufferedImage(buffimg.getWidth(), buffimg.getHeight(), BufferedImage.TYPE_INT_ARGB);
		
		Graphics buffg1=buffimg1.getGraphics();
		int x=e.getX();
		int y=e.getY();
		//获取像素点太快了
		if((Math.abs(x-oldx)*Math.abs(y-oldy))<100) {
			return;
		}
		else {
			oldx=x;
			oldy=y;
		}
		//根据坐标获取当前像素点的像素值
		int rgbvalue=buffimg.getRGB(x, y);
		
		//转成颜色 设置画笔 绘制方块
		Color color=new Color(rgbvalue);
		//g.setColor(color);
		//g.fillRect(x, y, 10, 10);
				//将处理后的 存储在buffimg中
		//buffg.setColor(color);
		buffg1.setColor(color);
		//System.out.println("color="+color);
		buffg1.fillRect(x, y, 10, 10);
		g.drawImage(buffimg1, 0, 0, null);
		//jp.repaint();//修改数据后使用paint刷新
	
		buffimgs[index++]=buffimg1;
		System.out.println("index="+index);
		//比如说我在原图画了一道局部马赛克 原图就变成带一道马赛克的了被覆盖了 局部马赛克与原图对应的是同一个对象
		//不断覆盖原来的 index(1-10++)全是一张图 需要使用新的bufferedimage
		
		
		}

		
		
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		 if(btnstrs.equals("截屏放置区域")) {
			x3=e.getX();
			y3=e.getY();
			//取当前图片
			BufferedImage buffimg=buffimgs[indexmsk-1];
			//创建一个新的空缓冲区
			BufferedImage buffimg1=new BufferedImage(buffimg.getWidth(), buffimg.getHeight(), BufferedImage.TYPE_INT_ARGB);
			Graphics buffg=buffimg1.getGraphics();
			for(int i=x1;i<=x2;i++) {
				for(int j=y1;j<=y2;j++) {
					int rgbvalue=buffimg.getRGB(i,j);
					Color color=new Color(rgbvalue);
					//buffimg1.setRGB(i, j, rgbvalue);	
					buffg.setColor(color);
					buffg.fillRect(i, j, 1, 1);

				}
			}
			g.drawImage(buffimg1,x3,y3,x2-x1,y2-y1,null);
			
			buffimgs[index++]=buffimg1;
			indexmsk++;
		}
		
	}
	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		super.keyPressed(e);
	}

}

ListenerUtils

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class ListenerUtils implements ActionListener,MouseListener,MouseMotionListener,KeyListener,ChangeListener{

	@Override
	public void stateChanged(ChangeEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
	}

	
}

ImageUI

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class ImageUI extends JPanel{
	String [] btnstrs= {"原图","马赛克","灰度","二值化","马赛克瓷砖","轮廓检测","手绘风格","怀旧","油画融合","局部马赛克","缩小","截屏放置区域","选择截屏区域","撤回"};
	static final ImageListener imageListener=new ImageListener();
	//对于变量,表示一旦给值就不可修改,并且通过类名可以访问。
	//对于方法,表示不可覆盖,并且可以通过类名直接访问。
	public static void main(String[] args) {
		new ImageUI().initUI();
		
	}
	
	
	public void initUI() {
		JFrame jf=new  JFrame("图形编程");
		jf.setSize(800,600);
		jf.setDefaultCloseOperation(3);
		jf.setLocationRelativeTo(null);
		
		// 按钮功能区面板 JPanel 
		JPanel jp1= new JPanel();
		jp1.setBackground(Color.DARK_GRAY);
		Dimension dim=new Dimension(120,0);
		jp1.setPreferredSize(dim);
		Dimension btndim=new Dimension(110,35);
		
		for(int i=0;i<btnstrs.length;i++) {
			JButton btn=new JButton(btnstrs[i]);
			btn.setBackground(Color.white);
			btn.setPreferredSize(btndim);
			btn.addActionListener(imageListener);
			jp1.add(btn);
			
			
		}
		
		//绘图区
		//JPanel jp2=new JPanel();
		this.setBackground(Color.BLACK);
		this.addMouseListener(imageListener);
		this.addMouseMotionListener(imageListener);
		this.addKeyListener(imageListener);
		
		
		jf.add(jp1,BorderLayout.EAST);
		jf.add(this);		
		jf.setVisible(true);
		Graphics g=this.getGraphics();
		imageListener.g=g;
		imageListener.jp=this;
		
	}
	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		//paint(g)函数会重绘图像,要加上super.paint(g),表示在原来图像的基础上,再画图。
		//如果不加super.paint(g),重绘时,会将原有的绘制清空,再根据paing(g)函数绘制。
		
		super.paint(g);//你改变界面的状态它就要重新画一次  在JPanel重画一次
		BufferedImage []imgs=imageListener.buffimgs;
		for(int i=0;i<imgs.length;i++) {
			//g.drawImage(imgs[i], 0, 0, null);
			if(imgs[i]==null) {
				return;
			}
			
			
			//创建新空缓冲图片对象
			g.drawImage(imgs[i], 0, 0,this.getWidth(),this.getHeight(), null);
			BufferedImage buffimg1=new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
			Graphics buffg1=buffimg1.getGraphics();
			//将发大后的缓冲图片放入新缓冲图片对象
			buffg1.drawImage(imgs[imageListener.index-1], 0, 0,this.getWidth(),this.getHeight(), null);
			//用放大后的图片替换
			imgs[imageListener.index-1]=buffimg1;
			//绘制新缓冲图片
			g.drawImage(buffimg1, 0, 0, null);
			System.out.println("i="+i);
		}
		
	}
	

}