最近刷抖音的时候发现一些图片转字符画的视频(如下图这样的)
AFF9147F9ABAC25EF450B2DF5225EFB1.png(网上也有在线工具,百度搜索图片转字符画可以搜索到)
乍一看 哇塞,好厉害,想了想其中的原理发现其实并没有多难。正好最近在学习C和C++,于是乎准备编程来实现。
首先找到这样一段ASCII字符
@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.
原理
这段ASCII字符是用来形容每个像素点的颜色深浅,从视觉效果(灰度)来看,字符的越复杂越能形容深色,我们只需要获得一张图并将这张图转化为灰度图,然后遍历其中的像素点的灰度值,并根据灰度值转化为相应的ASCII字符,最后存入一个txt文件中即可。
(注:使用windows的记事本打开时,需要将自动换行关闭,将字体改为宋体,大小小于4号才能看出效果)
然后开始编码
这里使用到了OpenCV库,主要用来做一些图片的转化,当然也可以使用别的方法来转换。
主要代码:
Mat srcImg = imread(imgFileName); //读取一张图片
Mat grayImg;
cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);//将图片转成灰度图
string str; //定义一个用来存储图片转换的字符的字符串
//循环遍历(灰度图)图片的每一个像素点
for(int y = 0; y < grayImg.rows; y++) {
for (int x = 0; x < grayImg.cols; x++) {
int grayVal = (int)grayImg.at<uchar>(y, x);
//获取每个像素点的灰度值,并根据灰度值对应ASCII字符数组中的的字符
//这里的69是定义的ASCII字符数组的长度,我直接写了
int index = 69 / 255.0 * grayVal;
str += codeLib[index];
}
str += "\r\n";
}
完整代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <string.h>
#include <fstream>
using namespace std;
using namespace cv;
void showImage(const char *winName, InputArray imgMat, int x, int y);
void outToFile(const char *fileName, const string content);
const char codeLib[] = "@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. ";
const char *imgFileName = "20161023140920353.jpg";
const char *outFileName = "test.txt";
int main() {
cout << strlen(codeLib) << " : " << codeLib << endl;
Mat srcImg = imread(imgFileName);
Mat grayImg;
cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);
string str;
for(int y = 0; y < grayImg.rows; y++) {
for (int x = 0; x < grayImg.cols; x++) {
int grayVal = (int)grayImg.at<uchar>(y, x);
// cout << grayVal << endl;
int index = 69.0 / 255.0 * grayVal;
str += codeLib[index];
}
str += "\r\n";
}
cout << str << endl;
outToFile(outFileName, str);
showImage("src", srcImg, 0, 0);
showImage("gray", grayImg, 100, 100);
waitKey(0);
return 0;
}
//显示图片
void showImage(const char *winName, InputArray imgMat, int x, int y){
namedWindow(winName, WINDOW_AUTOSIZE);
moveWindow(winName![20161023140920353.jpg](https://img.haomeiwen.com/i5652117/67ba56d0f67ed1f4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
, x, y);
imshow(winName, imgMat);
}
//将字符串写入文件
void outToFile(const char *fileName, const string content){
ofstream outStream;
outStream.open(fileName);
outStream << content << endl;
outStream.close();
}
结果
原图:
20161023140920353.jpg结果:
20180608112935.png项目地址
https://github.com/Sundae97/Image2Characters
参考文章
Python实现图片转字符画
网友评论