Java画蒙娜丽莎的微笑(记录)

原创
2012/12/21 23:39
阅读数 6.8K

最近在代码共享里共享了一份Java画蒙娜丽莎的微笑的源代码和资源文件,有人问我是怎么做的,这里简单说一下原理吧,很简单的,高手飘过吧~~。 一份是普通按行读取 一份是使用NIO读取

步骤:

1、找到原始图像

2、处理原始图像,读取像素点位置的颜色值 生成数据文件ml 

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import javax.imageio.ImageIO;

/**
 * 读取图片像素点颜色值
 * 
 * @author hoodoo
 * @date 2012年12月17日
 */
public class PicTools {
	private static final int PIXEL_W =1;
	private static final int PIXEL_H =1;

	/**
	 * 生成图像数据
	 * 
	 * @param img
	 * @param dataPath
	 */
	private void generatePicData(BufferedImage img, String dataPath) {
		StringBuilder sb = new StringBuilder();
		String R = null, G = null, B = null;
		int width = img.getWidth();
		int height = img.getHeight();
		int minx = img.getMinX();
		int miny = img.getMinY();
		sb.append(width).append(".").append(height).append("\r\n");
		int pixel = 0;
		for (int j = miny; j < height; j += PIXEL_H) {
			for (int i = minx; i < width; i += PIXEL_W) {
				pixel = img.getRGB(i, j);
				R = Integer.toHexString((pixel & 0xff0000) >> 16);
				G = Integer.toHexString((pixel & 0xff00) >> 8);
				B = Integer.toHexString(pixel & 0xff);
				R = R.length() == 1 ? "0" + R : R;
				G = G.length() == 1 ? "0" + G : G;
				B = B.length() == 1 ? "0" + B : B;
				sb.append(i).append("x").append(j).append("x").append(PIXEL_W)
						.append("x").append(PIXEL_H).append("x").append(R)
						.append(G).append(B).append("\r\n");
				
			}
		}
		try {
			writeByOutputStreamWrite(dataPath,sb.toString());
			sb.setLength(0);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	
	/**
	 * 用OutputStreamWrite向文件写入内容
	 * 
	 * @param _destFile
	 * @throws IOException
	 */
	public void writeByOutputStreamWrite(String _sDestFile,
			String _sContent) throws IOException {
		OutputStreamWriter os = null;
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(_sDestFile);
			os = new OutputStreamWriter(fos, "UTF-8");
			os.write(_sContent);
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (os != null) {
				os.close();
				os = null;
			}
			if (fos != null) {
				fos.close();
				fos = null;
			}

		}
	}

	/**
	 * 读取并生成数据
	 * 
	 * @param imgPath
	 */
	private void readAndGeneratePicData(String imgPath, String dataPath) {
		File file = new File(imgPath);
		BufferedImage img = null;
		try {
			img = ImageIO.read(file);
		} catch (Exception e) {
			e.printStackTrace();
		}
		generatePicData(img, dataPath);
	}

	public static void main(String[] args) {
		new PicTools().readAndGeneratePicData("d:\\ml.jpg", "src/ml");
	}
}
3、生成ml文件放在src下面,读取并逐点绘制 第一份是普通按行读取 第二份是使用NIO读取
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.swing.JFrame;

/**
 * Java画蒙娜丽莎的微笑
 * @author hoodoo
 * @date   2012年12月21日12:32:54
 */
public class PaintMonaLisa extends JFrame {
	private int x, y, R, G, B, w, h,imgW,imgH;
	private BufferedImage img;
	private Graphics imgG;
	public PaintMonaLisa() {
		this.setBackground(Color.BLACK);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Java画蒙娜丽莎的微笑  QQ:909854136    开源中国: @hoodoo");
	}

	@Override
	public void paint(Graphics g) {
		g.drawImage(img, 0, 0, null);
	}
	/**
	 * 读取数据文件 逐点绘制
	 * @param path
	 */
	public void readFileInfo(String path) {
		int i=0;
		BufferedReader bw=null;
		try {
			bw = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/" + path), "UTF-8")); 
			String line = null;
			while ((line = bw.readLine()) != null) {
				if(i==0){
					i=1;
					String temp[]=line.split("\\.");
					initWin(temp);
				}else{
					paintNextPoint(line);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(bw!=null){
				try {
					bw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	private void initWin(String[] temp) {
		imgW=Integer.parseInt(temp[0]);
		imgH=Integer.parseInt(temp[1]);
		this.setSize(imgW+20, imgH+20);
		this.setLocationRelativeTo(null);
		img = new BufferedImage(imgW, imgH,BufferedImage.TYPE_INT_ARGB);
		imgG = img.getGraphics();
	}
	/**
	 * 绘制下一个点
	 * @param point
	 */
	private void paintNextPoint(String point) {
		String[] s = point.split("x");
		x = Integer.parseInt(s[0]);
		y = Integer.parseInt(s[1]);
		w = Integer.parseInt(s[2]);
		h = Integer.parseInt(s[3]);
		R = Integer.parseInt(s[4].substring(0, 2), 16);
		G = Integer.parseInt(s[4].substring(2, 4), 16);
		B = Integer.parseInt(s[4].substring(4, 6), 16);
		imgG.setColor(new Color(R, G, B));
		imgG.fillRect(x+15, y+40, w, h);
		repaint();
	}

	public static void main(String[] args) {
		final PaintMonaLisa s = new PaintMonaLisa();
		s.open();
		s.readFileInfo("ml");
	}

	private void open() {
		this.setVisible(true);
	}

}

NIO读取版本

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import javax.swing.JFrame;

/**
 * Java画蒙娜丽莎的微笑
 * 
 * @author hoodoo
 * @date 2012年12月19日12:32:54
 */
public class PaintMonaLisa extends JFrame {
	private int x, y, R, G, B, w, h,imgW,imgH;
	private Color color;
	private int count;
	private int i;
	private int[] imgSize;
	private String[] imgData;
	private BufferedImage img;
	private Graphics imgG;

	public PaintMonaLisa3() {
		this.setBackground(Color.BLACK);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setTitle("Java画蒙娜丽莎的微笑  QQ:909854136    开源中国: @hoodoo");
	}

	@Override
	public void paint(Graphics g) {
		g.drawImage(img, 0, 0, null);
	}

	public void readFileInfo(String path) {
		FileInputStream fis = null;
		FileChannel channel=null;
		String s=null;
		try {
			fis = new FileInputStream(new File(path));
			channel = fis.getChannel();
			ByteBuffer buffer = ByteBuffer.allocate(1024*1024*5);
			channel.read(buffer);
			int size=(int) channel.size();
			byte[] bt = buffer.array();
			s = new String(bt, 0,  size);
			buffer.clear();
			buffer = null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			   try {
				    channel.close();
				    fis.close();
				   } catch (IOException e) {
				    // TODO Auto-generated catch block
				    e.printStackTrace();
				   }
		}
		String data[]=s.split("\r\n");
		count=data.length;
		while (i<count) {
			if(i==0){
				String temp[]=data[i].split("\\.");
				initWin(temp);
				i=1;
			}else{
				paintNextPoint(data[i]);
			}
		}
		
		
	}

	private void initWin(String[] temp) {
		imgW=Integer.parseInt(temp[0]);
		imgH=Integer.parseInt(temp[1]);
		this.setSize(imgW+20, imgH+20);
		this.setLocationRelativeTo(null);
		img = new BufferedImage(imgW, imgH,BufferedImage.TYPE_INT_ARGB);
		imgG = img.getGraphics();
	}
	/**
	 * 绘制下一个点
	 * @param point
	 */
	private void paintNextPoint(String point) {
		String[] s = point.split("x");
		x = Integer.parseInt(s[0]);
		y = Integer.parseInt(s[1]);
		w = Integer.parseInt(s[2]);
		h = Integer.parseInt(s[3]);
		R = Integer.parseInt(s[4].substring(0, 2), 16);
		G = Integer.parseInt(s[4].substring(2, 4), 16);
		B = Integer.parseInt(s[4].substring(4, 6), 16);
		imgG.setColor(new Color(R, G, B));
		imgG.fillRect(x+15, y+40, w, h);
		repaint();
		i++;
	}

	public static void main(String[] args) {
		PaintMonaLisa3 s = new PaintMonaLisa3();
		s.readFileInfo("src/ml");
		s.open();
	}

	private void open() {
		this.setVisible(true);
	}

}

展开阅读全文
加载中
点击加入讨论🔥(25) 发布并加入讨论🔥
打赏
25 评论
44 收藏
0
分享
返回顶部
顶部