一、介绍

字符画是一种纯由字符组成,在文本编辑器中行列排开的二维字符矩阵中,整体展示出可识别的图案。特点是无色,画面的最小单元是字符而非像素。可由基本的文本编辑器模拟图像。

字符画的展示:

蜡笔小心表情转换为字符画后的效果

字符画

原图片

二、原理

图片文件的本质是像素矩阵,每个点储存的有该点的色彩信息。计算机在处理图片时将每个点解析为不同的颜色,并显示在屏幕上构成了视觉上的图片。

单个像素点的颜色由三原色RGB三个变量决定。若RGB皆为0,即十六进制下的#000000,没有颜色填充的点,该点颜色为纯黑。RGB皆为255,即十六进制下的#FFFFFF,填充满三原色,混合为白色。

 灰度是表明像素点明暗程度的数值,也即黑白图像中点的颜色深度,范围在0到255,纯白为255 ,纯黑为0。灰度值指的是单个像素点的亮度。灰度值越大表示越亮。

字符画的实现是将源图片的RGB矩阵转换为灰度矩阵,再根据灰度的明暗程度选择不同密度的字符替换掉像素点,并打印该字符矩阵,即可得到字符画。          越亮的点,其占位字符密度越低,越暗的点,其占位字符密度高,即可在宏观程度上体现整幅图片的明暗变化。 

像素点由明到暗,相对于的字符集由稀疏到密集,定义拥有该特性的字符集。

这里提供一种有效的字符集:

char[] ss = " `.^,:~\"<!ct+{i7?u30pw4A8DX%#HWM".toCharArray();

该字符集从0下标开始,随着下标的递增,字符像素的密度也逐渐增大,模拟出了明暗的渐变效果,因此可作为灰度的映射。

三、实现

Java中用于处理图片的类是Image类,Image是一个抽象类,其实现类BufferedImage可以将图片加载到内存当中,其所表示的图片在内存中拥有一个缓冲区,因此可以很方便的操作图片。并且该实现类也提供了绘图相关的api。

本程序只需要获取图片的宽高属性,以及各像素点属性。

我们需要将字符通过IO流输出到指定文本文件内,之后打开该文件即可查看。因此采用字符缓冲流进行文件操作。

 BufferedWriter bw = new BufferedWriter(new FileWriter(target));

其中 target 为目标文本文件的路径,可填绝对路径,或相对路径(当前工作区开始)

定义BufferedImage并加载指定图片。

BufferedImage bi = ImageIO.read(Files.newInputStream(Paths.get(ImageSource)));
int width = bi.getWidth();
int height = bi.getHeight();

其中 ImageSource 为图片的文件路径。如:“D:\\picture\\1.jpg”。        加载完后调用BufferedImage对象的成员获取图片的宽高属性widthheight

对于单像素点的操作有

int pixel = bi.getRGB(i, j);
int[] rgb = new int[3];    //分别表示红绿蓝RGB。
rgb[0] = pixel >> 16 & 0xff;
rgb[1] = pixel >> 8 & 0xff;
rgb[2] = pixel & 0xff;

调用对象的 getRGB(int x,int y) 方法可以得到一个像素点色值的十六进制数返回值。若要分离RGB3个变量,可以通过位运算的方式,每次取其中的两位。

获取到一个像素点的RGB属性后,计算该点的灰度值。灰度值的计算一般有5种方法,如下:

1.浮点法:Gray=R*0.3+G*0.59+B*0.11

2.整数法:Gray=(R*30+G*59+B*11)/100

3.移位法:Gray =(R*77+G*151+B*28)>>8;

4.平均值法:Gray=(R+G+B)/3;

5.仅取绿色:Gray=G;

上述5种方法均有一定程度上的误差,在本程序中为了追求运算速度,采用移位计算以加快处理。即:

 int Gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8; //计算像素点的灰度int x = Gray * ss.length / 255 % ss.length;     //通过灰度的百分比 计算出相应密度的字符 在字符集中的位置。

通过以上计算,即可得该像素点会被替换为字符 ss[x] ,将替换后的字符打印,即实现了画出一个像素的的功能。

便利图片的所有像素点,在矩阵中打印转换后的字符。

    for (int j = 0; j < height; j += 2) {for (int i = 0; i < width; i += 2) {int pixel = bi.getRGB(i, j);int[] rgb = new int[3];rgb[0] = pixel >> 16 & 0xff;rgb[1] = pixel >> 8 & 0xff;rgb[2] = pixel & 0xff;int Gray = (rgb[0] * 28 + rgb[1] * 151 + rgb[2] * 77) >> 8; //通过三原色值计算像素点的灰度int x = Gray * ss.length / 255 % ss.length;     //灰度值的百分比 计算出相应密度的字符表bw.write(ss[x]);    //输出该字符bw.write(ss[x]);}bw.newLine();}bw.flush();

通过改变循环的控制变量的自增数值,可起到控制打印后文本文件长度也即“模拟像素”的大小的作用。

由于字符集中的字符为半角字符,在显示时高度总是为宽度的二倍,因此每个像素打印两倍的字符即可平衡宽高比。

测试代码,成功输出文本文件,可正常显示字符画。

四、扩展

由图片转换为字符画可联想到,是否可由动画转换为字符动画。

为了便于操作,这里采用的动画载体是gif文件。

导入jar包或引入坐标:

        <dependency><groupId>com.madgag</groupId><artifactId>animated-gif-lib</artifactId><version>1.4</version></dependency>

在源代码中导入包, 定义 GifDecoder 对象,并加载指定的gif文件。

import com.madgag.gif.fmsware.GifDecoder;GifDecoder gd = new GifDecoder();gd.read(Files.newInputStream(new File(gifSource).toPath()));

参数 gifSource 即gif资源文件的地址。 将之前描述的图片转字符画的步骤封装为方法 imageToChar方便调用。

通过GifDecoder对象的getFrameCount()方法获取帧数,getFrame(int x) 方法定位到第x帧图片。对每一帧图片进行转换处理。

for (int i = 0; i < gd.getFrameCount(); i++) {  //逐帧转换为字符集。BufferedImage frame = gd.getFrame(i);imageToChar(frame,"out.txt");    //参数提供缓冲图片对象,以及目标文本输出地址。Thread.sleep(50);
}

测试运行。

记事本打开的文本文件无法实时更新修改,查看运行效果建议使用NotePad++,或vscode。图片的大小建议在360p以内。若图片太大可通过修改像素坐标循环变量的自增值,来控制转换后的“像素”。

以下为动漫一拳超人中 主角琦玉的招式——认真一拳,所转换的字符动画展示。

本程序的代码实现思路较为简单明了,网上关于字符画的教程很多,笔者以较为擅长的java语言进行了一次修缮和总结。看到这读者可以点个赞支持下呀。

基于Java的图片字符画(含动图)相关推荐

  1. 基于JAVA黑白图片和上色处理系统(Springboot框架+AI人工智能) 开题报告

      本科生毕业论文 基于Java(springboot框架)黑白图片和上色处理系统 开题报告 学    院: 专    业: 计算机科学与技术 年    级: 学生姓名: 指导教师:   XXXX大学 ...

  2. java图片管理系统_基于Java的图片管理信息系统的设计与实现

    收稿日期:2003 - 05 - 07 作者简介:谭 娜(1978 -) ,女 ,河南济源人 ,硕士研究生 ,主要研究方向为数据库理论与应用. 基于 Java 的图片管理信息系统的设计与实现 谭 娜1 ...

  3. Python3,为了给女神暗送秋波,我默默的写了一个图片字符画生成器,真香。

    图片字符画制作 1.引言 2.代码实战 2.1 原理 2.2 实例 3.总结 1.引言 小屌丝:鱼哥,给你看个照片. 小鱼:什么-照片-首先声明,我可是正经人. 小屌丝:你先看看. 小鱼:就这,有啥好 ...

  4. 基于JAVA的图片相似度比对

    前言 一.工程简介 基于Java的图片相似度对比,有前台页面,后台算法 二.适用场景 图像处理实习 三.所用软件 此次工程,所用软件图片所示: 四.工程介绍

  5. 基于java的网上花店销售系统_基于JAVA的鲜花销售系统(含全套CAD图纸).doc

    基于JAVA的鲜花销售系统(含全套CAD图纸) 编号 太湖学院 毕业设计(论文) 题目: 信机 系 专业 学 号: 学生姓名: 指导教师: 201年5月2日太湖学院本科毕业设计(论文) 诚 信 承 诺 ...

  6. 五子棋游戏Java代码简单实现(含活动图和类图设计)

    五子棋游戏Java代码简单实现(含活动图和类图设计) 文章目录 五子棋游戏Java代码简单实现(含活动图和类图设计) 活动图设计 类图设计 代码实现 总结 OOA和OOD设计 代码设计 可改进部分 活 ...

  7. Python实践:画个动图玩玩,Python绘制GIF图总结

    Python实践:画个动图玩玩,Python绘制GIF图总结 文章目录 Python实践:画个动图玩玩,Python绘制GIF图总结 具体实现 Python代码 参考资料 上期博客< Pytho ...

  8. 怎么把图片转成gif动图?

    怎么把图片转成gif动图?所谓gif动图就是一种会动的图片,大家对这个应该不陌生,平时我们在微信聊天的时候总会看到的搞笑动态表情包就是一种常见的gif动图,但是动图的种类也是比较多得,最常见的gif动 ...

  9. 图片怎么合成gif动图?操作步骤详解

    图片怎么合成gif动图?gif动图的使用非常的广泛,平时我们聊天中见到的动态表情,已经逛某宝时看到的动态广告图,其实都是gif动图.小编作为一名互联网从业者,经常需要使用或者制作gif动态图片.不知道 ...

最新文章

  1. grpc 传递上下文_grpc 源码笔记 02:ClientConn
  2. NGUI的技能冷却实现
  3. 关于wifi的HW hdr error:len/check错误解决方法
  4. 想要玩转实现负载均衡,你知道这些吗?
  5. aardio教程_官方AARDIO课程已经开课了!学习的速来报道!
  6. Python使用numpy滤除图像中的低频信号
  7. 请用旧版的 Scala-2.11 搭配 Spark-2.4.8 / hadoop-2.7
  8. 传奇c语言编程,[转载]软件传奇Dennis M. Ritchie-c语言之父
  9. ENGINEER 05
  10. vr全景图如何制作?vr制作用什么软件?(详细教程)
  11. mac sierra mysql_Mac High Sierra一步搞定Mysql安装
  12. 如何提高个人执行力?
  13. EMNIST: an extension of MNIST to handwritten letters(数据集简介)
  14. yjk的波库在哪里_PKPM、YJK地震波导入至MIDAS软件中的方法
  15. 魔兽世界私服 服务器系统要求,全球最大《魔兽世界》私服有望重启 暴雪亲自运营...
  16. HTML 元素内容超出尺寸范围怎么办?
  17. abaqus的XFEM(扩展有限元)使用限制
  18. 解锁!玩转 HelloGitHub 的新姿势
  19. 借助AI生成PPT的网站
  20. golang常用方法积累

热门文章

  1. 四、shell编程四剑客
  2. openwrt配置动态挂载sd卡(二) -- openwrt默认配置挂载sd卡
  3. IJ开发工具 IntelliJ IDEA(简称IJ)建立JAVA项目详解
  4. 什么蓝牙耳机性价比高?总结5款高性价比平价蓝牙耳机
  5. 解聘未足额支付经济补偿如何确定劳动争议发生日
  6. TDateTime 日期时间值的比较
  7. 使用ZwCreateFile进行驱动调用驱动
  8. 同等学力申硕英语考试2021年备考策略
  9. python安卓app开发_[实例教程] 用python开发android应用
  10. AutoCAD 2009中文版基础入门教程下载