bmp图片中得到编码字符串_图片转字符串

f0b9b7d561c715afab1caf5f17e62218.png

图片转字符串

基本概念

灰度值

  • 把白色与黑色之间按对数关系分成若干级,称为“灰度等级”。范围一般从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对应的字符
40, 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

用到的函数

  • 图形库函数:
1getpixel()    获取某一点的颜色
2RGBtoGRAY()   通过rgb返回对应的灰度值颜色
3GetRValue()   得到RGB值中的红色部分,返回绿、蓝部分也可以
  • 文件操作 fputc()

示例代码:

 1#include<stdio.h>
 2#include<easyx.h>
 3char GetCh(int data);
 4char ch[] = { ' ', '`', '.', '^', ',', ':', '~', '"', '<', '!', 'c', 't', '+',
 5'{', 'i', '7', '?', 'u', '3', '0', 'p', 'w', '4', 'A', '8', 'D', 'X', '%', '#', 'H', 'W', 'M' };
 6char 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 };
 7int 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
42char 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++打开的,记事本也可以打开,但是要将字体设置小点才能看清楚,下面是原图和字符图的比较:

36268145886b0f27c4aa5c299f9f394d.png

0b37ebaf1b73ce72f175e964d35b867e.png

个人建议:

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值