通过之前的美图相机(http://t.csdn.cn/OvvWv)我们可以发现,最终所绘制出的图片是缓慢的展开的(可以理解为计算机现画图片,一个像素点一个像素点的绘制),那么要想让图片迅速展现,我们是不是可以将要绘制的图片现存在一个地方,在需要的绘制的时候,直接呈现出来。这就要利用到缓冲流了。
目录
<1> 缓冲流 原理
创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。要创建缓冲区数组,也就意味着需要占据内存!
数据读取速度:寄存器 > 内存 > 磁盘
<2> 具体流程
1、首先我们需要先创建一个BufferedImage 的缓冲区
//提升速度
BufferedImage buffimg = new BufferedImage(
imageArr.length,imageArr[0].length,
BufferedImage.TYPE_INT_ARGB
);
2、让缓冲区的对象获得RBG
buffimg.setRGB(i, j, pixnum);
3、用画笔画出结果
g.drawImage(buffimg, 100, 50, null);
<3> 绘制原图 完整代码
/*
* 绘制原图
*/
public void drawImage(int[][] imageArr,Graphics g) {
//提升速度
BufferedImage buffimg = new BufferedImage(
imageArr.length,imageArr[0].length,
BufferedImage.TYPE_INT_ARGB
);
for(int i = 0;i < imageArr.length;i++) {
for(int j = 0;j < imageArr[i].length;j++) {
int pixnum = imageArr[i][j];
buffimg.setRGB(i, j, pixnum);
}
}
g.drawImage(buffimg, 100, 50, null);
}
<4> 绘制灰度图 完整代码
/*
* 绘制灰度图
*/
public void drawGrayImage(int[][] imageArr,Graphics g) {
//提升速度
BufferedImage buffimg = new BufferedImage(
imageArr.length,imageArr[0].length,
BufferedImage.TYPE_INT_ARGB
);
for(int i = 0;i < imageArr.length;i++) {
for(int j = 0;j < imageArr[i].length;j++) {
int pixnum = imageArr[i][j];
//将像素拆开
int red = (pixnum >> 16)&255;
int green = (pixnum >> 8)&255;
int blue = (pixnum >> 0)&255;
//灰度运算(R=G=B)
int gray = (red + green + blue)/3;
int colorgray = 255<<24|gray<<16|gray<<8|gray;
buffimg.setRGB(i, j, colorgray);
}
}
g.drawImage(buffimg, 100, 50, null);
}
<5> 绘制二值化图 完整代码
/*
* 二值化
*/
public void drawBinaryImage(int[][] imageArr,Graphics g) {
//提升速度
BufferedImage buffimg = new BufferedImage(
imageArr.length,imageArr[0].length,
BufferedImage.TYPE_INT_ARGB
);
for(int i = 0;i < imageArr.length;i++) {
for(int j = 0;j < imageArr[i].length;j++) {
int pixnum = imageArr[i][j];
//将像素拆分
int red = (pixnum >> 16)&255;
int green = (pixnum >> 8)&255;
int blue = (pixnum >> 0)&255;
//计算灰度值
int gray = (red+green+blue)/3;
//利用灰度值做二分法
int colorgray = 0;
if(gray<125) {
colorgray = 255<<24|0000<<16|0000<<8|0000;
}else {
colorgray = 255<<24|1011<<16|1011<<8|1011;
}
buffimg.setRGB(i, j, colorgray);
}
}
g.drawImage(buffimg, 100, 50, null);
}
<5> 绘制马赛克 完整代码
马赛克的绘制与原图一样,只不过需要注意马赛克是一个方块一个方块,原图是一个一个的像素点,所以我们需要将缓冲的画笔赋值给画笔对象bg,再用bg去获得像素颜色绘制出方块。
(若我们只在原图的基础上修改for循环i++ --> i+10,会导致所绘制出来的是一个一个间隔较远的像素点)
/**
* 马赛克
*/
public void drawMosaicImage(int[][] imageArr,Graphics g) {
//提升速度
BufferedImage buffimg = new BufferedImage(
imageArr.length,imageArr[0].length,
BufferedImage.TYPE_INT_ARGB
);
Graphics bg = buffimg.getGraphics();
for(int i = 0;i < imageArr.length;i+=10) {
for(int j = 0;j < imageArr[i].length;j+=10) {
int pixnum = imageArr[i][j];
Color color = new Color(pixnum);
bg.setColor(color);
bg.fillRect(i, j, 8, 10);//画方块
}
}
g.drawImage(buffimg, 100, 100, null);
}
融合的缓冲和上面的一样