最近在代码共享里共享了一份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);
}
}