图片转字符图片
Posted lossingdawn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图片转字符图片相关的知识,希望对你有一定的参考价值。
序言
这个是从抖音上学来的,一开始刷抖音,遇到不少字符串跳舞的视频,因此来实践一下
主要分为三个部分
- 静态图片转静态图片
- gif转gif
- 视频转视频
静态图片转静态图片
其实原理很简单,读取图片的像素,新建一张大小一样的图片,根据原图像素的灰度,决定是不是要显示出来,并在新图相应的位置添加字符,这样就完成了
借助前辈写的工具,主要包含一下四个类:
AnimatedGifEncoder
GifDecoder
LZWEncoder
NeuQuant
源地址
https://github.com/rtyley/animated-gif-lib-for-java
ps: 网上各种版本的太多,不清楚这个是不是原作者,github上搜GifDecoder,有不少
环境:
JDK 1.8
注:Java原生代码实现使用jdk内部的GIFImageReader、GIFImageWriter等类,maven在编译的时候会提示这是sun公司的私有API,在1.7、1.8版的JDK中已经删除,所以是有风险的。在此使用ImageIO这个类来进行图片的操作。
主要代码如下所示:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @ClassName: ImgUtil
* @Description: TODO
* @author jiang
* @date 2018年8月14日 下午10:15:56
*
*/
public class ImgUtil {
static Logger logger = LoggerFactory.getLogger(ImgUtil.class);
public static boolean toTextImg(String inputFile, String outputFile, final String base, int threshold) {
// String blackFile = "F:/123/head_black.png";
BufferedImage src = null;
BufferedImage tag = null;
boolean res = false;
try {
src = ImageIO.read(new FileInputStream(inputFile));
int[] rgb = new int[3];
int width = src.getWidth();
int height = src.getHeight();
int minx = src.getMinX();
int miny = src.getMinY();
// 黑白化
/*-
src = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(src, null);
res = ImageIO.write(src, blackFile.substring(blackFile.lastIndexOf(".") + 1), new File(blackFile));
src = ImageIO.read(new FileInputStream(blackFile));*/
tag = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = tag.getGraphics();
g.setFont(new Font("微软雅黑", Font.PLAIN, 10));// 设置字体
g.setColor(Color.BLUE);// 设置颜色
for (int x = minx; x < width; x += 6) {
for (int y = miny; y < height; y += 6) {
int pixel = src.getRGB(x, y); // 下面三行代码将一个数字转换为RGB数字
rgb[0] = (pixel & 0xff0000) >> 16;// red
rgb[1] = (pixel & 0xff00) >> 8;// green
rgb[2] = (pixel & 0xff);// blue
final float gray = 0.299f * rgb[0] + 0.578f * rgb[1] + 0.114f * rgb[2];
final int index = Math.round(gray * (base.length() + 1) / 255);
// logger.debug("{},{}",index,base.length() / threshold);
if (index <= threshold) {
g.drawString(String.valueOf(base.charAt(index % base.length())), x, y);// 文字的编写及位置
}
/*-
if (rgb[0] + rgb[1] + rgb[2] <= 500) {
System.out.println("i=" + i + ",j=" + j + ":(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")");
g.drawString("v", i, j);// 文字的编写及位置
}*/
}
}
g.dispose();
// 输出图片
res = ImageIO.write(tag, outputFile.substring(outputFile.lastIndexOf(".") + 1),
new File(outputFile));
logger.debug("字符化结果:{}", res);
} catch (IOException e) {
logger.error("err", e);
return false;
}
return true;
}
}
代码的思路很简单,src.getRGB(x, y)
获取具体像素点的颜色值,共六位,每两位一个颜色值,依次是red
green
blue
,类似的使用(pixel & 0xff0000) >> 16
获取第一位的红色等,根据灰度公式Gray = R*0.299 + G*0.587 + B*0.114
计算灰度(百度颜色灰度公式
,有很多来计算心理灰度的解决方案),选择合适的灰度替换上合适的字符即可
源码地址:
https://github.com/Ruffianjiang/java4fun/tree/master/img2text
参考:
以上是关于图片转字符图片的主要内容,如果未能解决你的问题,请参考以下文章
图片转ascii网站(图像转字符图片转字符字符画字符图图像转ascii)