图片转字符串

图片转字符串

基本概念
灰度值

  • 把白色与黑色之间按对数关系分成若干级,称为“灰度等级”。范围一般从0到255,白色为255,黑色为0,黑白照片也称为灰度图像

  • RGB值和灰度值的换算公式 Gray=(R30+G59+B*11)/100,转换后的颜色就是RGB(Gray,Gray,Gray)

字符画

  • 字符画就是用若干个字符组成,每个字符去替换原图的一块区域

  • 有些字符会更接近白色(比如.),有些会更接近黑色(比如M),根据某一块的平均灰度找到最接近的字符即可

  • 字符和接近的灰色值已经给出

1  字符
2  ' ', '`', '.', '^', ',', ':', '~', '"', '<', '!', 'c', 't', '+', '{', 'i', '7', '?','u', '3', '0', 'p', 'w', '4', 'A', '8', 'D', 'X', '%', '#', 'H', 'W', 'M',
3  对应的字符
4  0, 5, 7, 9, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,45, 47, 49, 51, 53, 55, 59, 61, 63, 66, 68, 70

用到的函数

图形库函数:

1  getpixel()    获取某一点的颜色
2  RGBtoGRAY()   通过rgb返回对应的灰度值颜色
3  GetRValue()   得到RGB值中的红色部分,返回绿、蓝部分也可以

文件操作 fputc()

示例代码:

 1 #include<stdio.h>
 2 #include<easyx.h>
 3 char GetCh(int data);
 4 char ch[] = { ' ', '`', '.', '^', ',', ':', '~', '"', '<', '!', 'c', 't', '+',
 5 '{', 'i', '7', '?', 'u', '3', '0', 'p', 'w', '4', 'A', '8', 'D', 'X', '%', '#', 'H', 'W', 'M' };
 6 char num[] = { 0, 5, 7, 9, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,43, 45, 47, 49, 51, 53, 55, 59, 61, 63, 66, 68, 70 };
 7 int main()
 8 {
 9    IMAGE img;
10    loadimage(&img, L"test.bmp");
11    initgraph(img.getwidth(), img.getheight());
12    putimage(0, 0, &img);
13    FILE *fp = fopen("图片转字符.txt", "w");
14    if (!fp) return 0;
15
16    int gray;   //灰度值
17    for (int i = 0; i < img.getheight() / 8; ++i)
18    {
19        for (int j = 0; j < img.getwidth() / 8; ++j)
20        {
21            gray = 0;   //清零
22            for (int x = 0; x < 8; ++x)
23            {
24                for (int y = 0; y < 8; ++y)
25                {
26                    //统计这个区域中的灰度值 求平均
27                    gray += GetRValue(RGBtoGRAY(getpixel(j * 8 + x, i * 8 + y)));
28                }
29            }
30            gray /= 8 * 8;  //取平均值
31            //将灰度值  转换成0~70之间的值  匹配数组中的数字  找到对应字符
32            fputc(GetCh(70 - gray * 70 / 255), fp);//0~255之间  --->0~70之间的数字 
33        }
34        fputc('\n', fp);//每一行加个换行符号
35    }
36    fclose(fp);
37    getchar();
38    closegraph();
39    return 0;
40}
41
42 char GetCh(int data)
43{
44    //快速查找
45    int left = 0, right = 31, index;    //num的最大元素下标是31
46    while (left < right)
47    {
48        index = (left + right) / 2;
49        if (num[index] == data) return ch[index];       //找到数字 直接返回对应的字符
50        else if (num[index]>data) right = index - 1;    //往左找
51        else left = index + 1;
52    }
53    //退出的条件  left>=right
54    return ch[left];    //return ch[right]也可以           
55}

我用的Notepad++打开的,记事本也可以打开,但是要将字体设置小点才能看清楚,下面是原图和字符图的比较:

在这里插入图片描述

在这里插入图片描述

个人建议:

我本人不建议使用Windows自带的记事本编辑文本文件。原因是Microsoft开发记事本的团队使用了一个愚蠢的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,拖拽到Linux系统的文本文件打开乱码,这是使用记事本带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8【菜单栏–选择编码–选择UTF-8编码】。

下载地址:
https://notepad-plus-plus.org/downloads/v7.8.2/

发布了12 篇原创文章 · 获赞 0 · 访问量 661

猜你喜欢

转载自blog.csdn.net/xiangxin1030/article/details/103925439