赞
踩
当然,有了原理我们还需要通过实践来验证。我们来编写一个java程序实现将上面给出的test.png这张图片字符化。我将使用字符来描述一张图片称为图片字符化。
首先定义一个字符串,用于做替换的。
private final static String IMG_ASCII = "@#&$%*o!;.";
编写一个方法,该方法要做的事情如下:
根据传递进来的图片路径信息读取图片,就是将图片文件加载到内存中。
// 读取图片文件到内存
BufferedImage image = ImageIO.read(new File(imgPath));
获取图片的宽高,根据宽度限制循环范围遍历图片的每一个像素,获取到每一个像素的rgb值。
// 获取图片宽度和高度
int width = image.getWidth();
int height = image.getHeight();
// 遍历图片像素,x横坐标,y纵坐标
for (int y = 0; y
for (int x = 0; x
int rgb = image.getRGB( x,y);
}
}
由于获取到的这个rgb值是包含r、g、b的值在里面的,所以需要分解分别获取到r的值、g的值和b的值。
//返回的颜色值是个整数,即四个字节,这四个字节保存的值从高位到低位分别位透明度a、r、g、b。
int r = (rgb & 0xff0000)>>16;
int g = (rgb & 0xff00)>>8;
int b = (rgb & 0xff);
计算灰度值
//计算灰度值
int gray = (r+g+b)/3;
获取到该像素的替换字符
//计算替换的下标
int index = gray*(IMG_ASCII.length()+1)/255;
char asc = index>IMG_ASCII.length()-1?' ':IMG_ASCII.charAt(index);
为了简单,我这里只是将替换后的字符直接输出,只是为了看效果。如果你想将替换结果保存为图片,给你提供一个思路,就是将替换后的字符按照坐标保存到数组中,然后将这些字符绘制到一张画布上,从画布中获取bitmap将其保存为图片。
private static void testImg2Ascii(String imgPath) throws IOException{
// 读取图片文件到内存
BufferedImage image = ImageIO.read(new File(imgPath));
// 获取图片宽度和高度
int width = image.getWidth();
int height = image.getHeight();
// 遍历图片像素,x横坐标,y纵坐标
for (int y = 0; y
for (int x = 0; x
//获取rgb
//getRGB官方的描述:
//Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace. Color conversion takes place if this default model does not match the image ColorModel
. There are only 8-bits of precision for each color component in the returned data when using this method.
//中文大概意思:返回默认RGB颜色模型(TYPE_INT_ARGB)和默认sRGB颜色空间中的整数像素。
//如果此默认模型与图像ColorModel不匹配,则进行颜色转换。
//使用此方法时,返回数据中的每个颜色组件只有8位精度。
int rgb = image.getRGB( x,y);
//返回的颜色值是个整数,即四个字节,这四个字节保存的值从高位到低位分别位透明度a、r、g、b。
int r = (rgb & 0xff0000)>>16;
int g = (rgb & 0xff00)>>8;
int b = (rgb & 0xff);
//计算灰度值
int gray = (r+g+b)/3;
//计算替换的下标
int index = gray*(IMG_ASCII.length()+1)/255;
char asc = index>IMG_ASCII.length()-1?' ':IMG_ASCII.charAt(index);
//打印字符
System.out.print(asc);
}
System.out.println();
}
image.flush();
}
编写一个main方法测试一下,在main方法中传入图片的绝对路径:
try {
testImg2Ascii("/Users/wjy/Desktop/test.png");
} catch (IOException e) {
e.printStackTrace();
}
建议测试的图片选择小点的,不然会看不出效果。如果你想做得完善一点就需要做图片的大小压缩质量压缩等处理了。
你也可以将图片的像素遍历改成这样,达到压缩图片宽高的效果。比如想将宽度压缩4倍就可以将x坐标设为每隔四个点取一个像素,想将高度压缩8倍就可以将y坐标设为每隔八个点取一个像素。
// 遍历图片像素,x横坐标,y纵坐标
for (int y = 0; y
for (int x = 0; x
.......
}
}
效果结果:
动图实现思路
实现动图的转换无非就是将动图解析成一帧帧图片,将每张图片转成ascii字符后保存为图片,最后将转换后的图片重组成gif图。
也可以不用这么麻烦,其实你将转换后每帧图片输出的ascii保存到对应的一个文本文件,最后使用录屏工具弄成gif图,或者截图再使用ps来弄都是可以的。
由于这个过程实现起来还是有点费时间的,所以这里我只是说个实现思路,如果你想做出来玩的话就需要你自己去折腾了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。