实现原理
将图片分解为像素点然后计算出每个点的灰度值,根据不同灰度使用不同的字符进行填充。
以下代码实现了将图片缩放至指定宽高并转换为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:甥敳獲MyDesktop1.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(); }}
最终效果图如下: