一個(gè)簡(jiǎn)單的圖片轉(zhuǎn)字符畫(huà)程序(C++實(shí)現(xiàn))

最近刷抖音的時(shí)候發(fā)現(xiàn)一些圖片轉(zhuǎn)字符畫(huà)的視頻(如下圖這樣的)
AFF9147F9ABAC25EF450B2DF5225EFB1.png

(網(wǎng)上也有在線工具,百度搜索圖片轉(zhuǎn)字符畫(huà)可以搜索到)

乍一看 哇塞,好厲害,想了想其中的原理發(fā)現(xiàn)其實(shí)并沒(méi)有多難。正好最近在學(xué)習(xí)C和C++,于是乎準(zhǔn)備編程來(lái)實(shí)現(xiàn)。

首先找到這樣一段ASCII字符

@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'. 

原理

這段ASCII字符是用來(lái)形容每個(gè)像素點(diǎn)的顏色深淺,從視覺(jué)效果(灰度)來(lái)看,字符的越復(fù)雜越能形容深色,我們只需要獲得一張圖并將這張圖轉(zhuǎn)化為灰度圖,然后遍歷其中的像素點(diǎn)的灰度值,并根據(jù)灰度值轉(zhuǎn)化為相應(yīng)的ASCII字符,最后存入一個(gè)txt文件中即可。
(注:使用windows的記事本打開(kāi)時(shí),需要將自動(dòng)換行關(guān)閉,將字體改為宋體,大小小于4號(hào)才能看出效果)

然后開(kāi)始編碼

這里使用到了OpenCV庫(kù),主要用來(lái)做一些圖片的轉(zhuǎn)化,當(dāng)然也可以使用別的方法來(lái)轉(zhuǎn)換。

主要代碼:

    Mat srcImg = imread(imgFileName);  //讀取一張圖片
    Mat grayImg;
    cvtColor(srcImg, grayImg, COLOR_RGB2GRAY);//將圖片轉(zhuǎn)成灰度圖

    string str;    //定義一個(gè)用來(lái)存儲(chǔ)圖片轉(zhuǎn)換的字符的字符串

    //循環(huán)遍歷(灰度圖)圖片的每一個(gè)像素點(diǎn)
    for(int y = 0; y < grayImg.rows; y++) {
        for (int x = 0; x < grayImg.cols; x++) {
            int grayVal = (int)grayImg.at<uchar>(y, x);
            //獲取每個(gè)像素點(diǎn)的灰度值,并根據(jù)灰度值對(duì)應(yīng)ASCII字符數(shù)組中的的字符
            //這里的69是定義的ASCII字符數(shù)組的長(zhǎng)度,我直接寫(xiě)了
            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://upload-images.jianshu.io/upload_images/5652117-67ba56d0f67ed1f4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
, x, y);
    imshow(winName, imgMat);
}

//將字符串寫(xiě)入文件
void outToFile(const char *fileName, const string content){
    ofstream outStream;
    outStream.open(fileName);
    outStream << content << endl;
    outStream.close();
}

結(jié)果

原圖:
20161023140920353.jpg
結(jié)果:
20180608112935.png

項(xiàng)目地址

https://github.com/Sundae97/Image2Characters

參考文章
Python實(shí)現(xiàn)圖片轉(zhuǎn)字符畫(huà)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容