【轻松一刻】Java制作字符动画

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/loveqishan/article/details/89945304

前言

今晚闲来无事,整理了一下电脑中尘封已久的旧代码,看着那些年自己写过的代码,踩过的坑,顿时老泪纵横。正当在感叹之际,突然发现在“马克思”文件夹下出现了一个好玩的项目,那就是N年前刚学Java时写的GIF转字符动画的小玩具,虽然是个小玩意,但是在当时能搞点东西出来还是非常有成就感的。

正文

效果展示

原图,某两年半练习生

转成字符动画后的练习生

实现原理

其实字符动画的实现原理比较简单,这里我们抛开GIF,直接拿一张静态图片来说明。
首先我们要把原图转成灰度图,这样图片中每个像素就只存在亮度信息0-255。

取颜色的RGB均值灰度后

接着我们可以定义需要使用的字符,每个字符对应一段亮度范围,比如 图中的M,@,;等字符,接着我们就可以去遍历替换图片中的所有像素,慢慢的调试每个字符对应像素的亮度范围,调试到输出的图像轮毂清晰即可,这样单张图片的字符画就已经成型了。下面关键代码注释。

BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
		int width = bi.getWidth();//原图宽度
		int height = bi.getHeight();//原图高度
		int minx = bi.getMinX();//BufferedImage 原图 最小X坐标
		int miny = bi.getMinY(); //BufferedImage 原图 最小Y坐标
		for (int i = miny; i < height; i += 8) {//遍历图片中的像素点,用字符判断像素范围来替换
			for (int j = minx; j < width; j += 8) {
				int pixel = bi.getRGB(j, i); // 下面三行代码将一个数字转换为RGB数字
				int red = (pixel & 0xff0000) >> 16;
				int green = (pixel & 0xff00) >> 8;
				int blue = (pixel & 0xff);
				double gray = 0.299 * red + 0.578 * green + 0.114 * blue; //图片变灰计算公式
				char c = toChar((int) gray); //根据计算出来的gray值返回不同字符
				bufferedWriter.write(c);
			}
			bufferedWriter.newLine();
		}
		//输出图片

若要读取GIF,输出GIF,我们可以使用一些开源的包,例如animated-gif,GifDecoder等,通过这些类我们可以读取到gif的每一帧,然后我们对每一帧的操作都跟上方的静态图操作是一致的。处理完每一帧之后再合成GIF输出即可。(视频同理)

由于完全自己处理的话,可能会有很多细节需要调整的地方,为了方便,这里推荐一个项目。Github地址:https://github.com/korhner/asciimg 。使用方法:

// initialize caches
AsciiImgCache smallFontCache = AsciiImgCache.create(new Font("Courier",Font.BOLD, 6));
// initialize ssimStrategy
BestCharacterFitStrategy ssimStrategy = new StructuralSimilarityFitStrategy();

String srcFilePath = "examples/xxx.gif";
String disFilePath = "examples/xxx.gif";
int delay = 100;//ms

GifToAsciiConvert asciiConvert = new GifToAsciiConvert(smallFontCache, ssimStrategy);

asciiConvert.convertGitToAscii(srcFilePath, disFilePath, delay,0);

只需要简单的几行,就可以完成字符动画的转换,其原理跟我们上面介绍的基本一致,有兴趣的同学可以自行研究。

结语

代码除了用来工作,其实还能用在很多能让我们开心的地方,例如写点小工具,小游戏,帮自己或他人解决一些繁琐的事情,这样才能在工作多年后任然保持对代码的那份初心,不至于被重复的工作磨灭了激情。


公众号博文同步Github仓库,有兴趣的朋友可以帮忙给个Star哦,码字不易,感谢支持。

https://github.com/PeppaLittlePig/blog-wechat

推荐阅读

如何优化代码中大量的if/else,switch/case?
如何提高使用Java反射的效率?
Java日志正确使用姿势

有收获的话,就点个赞吧

关注「深夜里的程序猿」,分享最干的干货

展开阅读全文

轻松一刻!

04-10

(幽默网文)央视名嘴与《天龙八部》 rnrnrn 1.宋世雄:(一口气说完以下内容)叶二娘把内力传给南海鳄神,南海鳄神把内力传给一位年轻公子,年轻公子便是段誉。观众朋友我们进行了统计,段誉这段时间吸内力8人,四大恶人3人,黄眉僧1人,崔百泉1人,钟万仇一家3人……rn  2.韩乔生:乔帮主人称北乔峰,耶律洪基不惜重金升他为南院大王,前日在塞北平反了皇叔叛乱,今天是否能在少林寺再次发威,我们将和观众朋友拭目以待!rnrn  3.黄健翔:在我们直播的这场萧峰对游坦之比赛期间,我们也会播报其他场次的比分。哦?!在另一边虚竹已经2:0领先丁春秋了!而在另一场保级战中段誉2:1将慕容复反超!这两场比赛也是我们这次竞猜的范围……rnrn  4.张路:萧峰这个人呢,攻守比较平衡……看这一掌!!……哎哟!危险!!攻守比较平衡,招数也不少,……看这次进攻……啊呀!机会!!……rnrn  5.段暄:这场比赛也是吸引了(停顿1.5秒)大批的丐帮帮众到现场观战,因为不论是(停顿1秒)萧峰取胜还是(停顿1秒)游坦之称雄,这都将是一场(停顿2秒)伟大的(停顿1秒)比赛。rnrn  6.慕容复准备做答……rnrn  王小丫:你准备好了吗?rnrn  慕容复:准备好了。rnrn  王小丫:好。请选择复国的最佳地点:a.大宋b.大辽c.西夏d.大理rnrn  慕容复:我想电话求助。rnrn  王小丫:可以,打给谁?rnrn  慕容复:我爹。rnrn  王小丫:好(电话播通)。喂,是慕容老先生吗?你好,你的儿子要和你通话。你们只有30秒的时间。rnrn  慕容复:喂!爹啊!复国的最佳地点是a.大宋b.大辽c.西夏d.大理。选哪个啊?rnrn  慕容博:庶民如尘土,帝王亦如尘土。大燕不复国是空,复国亦空。rnrn  慕容复:啊???rnrn  王小丫:好,时间到,决定了吗?rnrn  慕容复:嗯,那就b吧。大辽。rnrn  王小丫(含情脉脉地):你确定吗?rnrn  慕容复(深吸一口气):确定。rnrn  王小丫(含情脉脉地):不改了吗?rnrn  慕容复(深吸一口气):不改了。rnrn  王小丫:好,那么答案到底对不对?我们先看一段广告,广告之后告诉你。rnrn  (慕容复晕倒……)rnrn  7.李咏:下面请慕容复为萧峰选题,是这样一组:杏子林,聚贤庄,青石桥,少林寺,雁门关。rnrn  慕容复:我看雁门关对他比较重要,就给他雁门关吧!rnrn  李咏:好,雁门关。萧峰请接题:雁门关你用两截断箭自刺胸腹时,有一群鸿雁飞过,是排成:a.横一字。b.竖一字。c.人字型。d.没排阵型。萧峰,请做答。rnrn  萧峰:(冥思苦想状)我忘了,我选d。rnrn  李咏:哎呀真可惜,如果你记得你就……好,正确的答案是:……(环顾紧张的慕容复和萧峰)……没排阵型!!!!恭喜萧峰!!!(萧峰狂喜高举双臂,并礼貌地与慕容复握手……台下丐帮帮众笑成一片)rnrn  李咏:好,台下穿乞丐衣服的朋友你们将得到XXX表业提供的精美礼品一份! 论坛

新海湾战争之台前幕后!----轻松一刻

03-24

rn亚速尔峰会前夕,布什为最后争取法德对倒萨战争的支持,授意 rnrn布莱尔与希拉克、施罗德秘密会晤,但会谈并不顺利。 rn会议间隙,布莱尔为缓和气氛,向希拉克搭讪道:“希兄,您的 rnrn聪明才智我非常佩服,请教一个问题,您如何判断和您打交道的 rnrn家伙是聪明人还是傻瓜呢?” rn希拉克答道:“我会请他猜一个谜语。” rn“什么谜语?” rn希拉克笑了笑,望向施罗德问道:“总理阁下,请问如果您父母 rnrn的孩子不是您的兄弟姐妹,那么他是谁?” rn施罗德答:“是施罗德。” rn布莱尔愣了一会儿,随即会意。 rn会后,布莱尔打电话给布什,通报了会议的情况。布什说:“没 rnrn关系,我们会有新的计划。” rn布莱尔灵机一动,问道:“布兄,我听到一个谜语:请问如果您 rnrn父母的孩子不是您的兄弟姐妹,那么他是谁?” rn布什支吾道:“我想一想再告诉你。” rn布什给基辛格打电话:“请问如果您父母的孩子不是您的兄弟姐 rnrn妹,那么他是谁?” rn基辛格想了一下,回答道:“是基辛格。” rn布什又给布莱尔打电话:“我想到了,是基辛格。” rn布莱尔回道:“不对吧,布兄,答案应该是施罗德呀!” rn布什说:“算了,我们还是说正事吧。” rn随后,3月16日,美、英、西、葡四国在大西洋中的亚速尔群岛 rnrn举行了关于伊拉克问题的四方首脑会晤。rnrnrn rn 论坛

没有更多推荐了,返回首页