实现原理
将图片分解为像素点然后计算出每个点的灰度值,根据不同灰度使用不同的字符进行填充。
以下代码实现了将图片缩放至指定宽高并转换为ASCII字符画的功能。
package com.wunian.ascii;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @author wunian
* @desc 实现图片转AscII字符画
* @createTime 2020/7/15
*/
public class AsciiPicDemo {
public static void main(final String[] args) throws Exception {
String src = "C:\\Users\\My\\Desktop\\1.gif";
String dest = src.substring(0,src.lastIndexOf("\\")+1)+"_"+ UUID.randomUUID()+"_"+src.substring(src.lastIndexOf("\\")+1);
String path = zoomImage(src,dest,80,50);
createAsciiPic(path);
}
/**
* 生成ASCII字符画
* @param path 图片路径
*/
public static void createAsciiPic(String path) {
final String base = "▬@*&$^";// 字符串由复杂到简单
try {
BufferedImage image = ImageIO.read(new File(path));
//可以通过改变x和y的步长来控制字符画的字符稀疏程度
for (int y = 0; y < image.getHeight(); y += 1) {
for (int x = 0; x < image.getWidth(); x += 1) {
final int pixel = image.getRGB(x, y);
final int r = (pixel & 0xff0000) >> 16, g = (pixel & 0xff00) >> 8, b = pixel & 0xff;
final float gray = 0.299f * r + 0.578f * g + 0.114f * b;
final int index = Math.round(gray * (base.length() + 1) / 255);
System.out.print(index >= base.length() ? " " : String.valueOf(base.charAt(index)));
}
System.out.println();
}
} catch (final IOException e) {
e.printStackTrace();
}
new File(path).delete();//删除临时文件
}
/**
* 图片缩放,生成指定宽高的目标图片
* @param src 源文件目录
* @param dest 缩放后保存目录
* @param w 缩放的目标宽度
* @param h 缩放的目标高度
* @return
* @throws Exception
*/
public static String zoomImage(String src,String dest,int w,int h) throws Exception {
double wr=0,hr=0;
File srcFile = new File(src);
File destFile = new File(dest);
BufferedImage bufImg = ImageIO.read(srcFile); //读取图片
System.out.println("width:"+bufImg.getWidth());
System.out.println("height:"+bufImg.getHeight());
Image Itemp = bufImg.getScaledInstance(w, h, bufImg.SCALE_SMOOTH);//设置缩放目标图片模板
wr=w*1.0/bufImg.getWidth(); //获取缩放比例
hr=h*1.0 / bufImg.getHeight();
AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
Itemp = ato.filter(bufImg, null);
try {
ImageIO.write((BufferedImage) Itemp,dest.substring(dest.lastIndexOf(".")+1), destFile); //写入缩减后的图片
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("getAbsoultePath:"+destFile.getAbsolutePath());
return destFile.getAbsolutePath();
}
}
效果图如下:
网友评论