图片转化为 ASCII 图,就是很多字符组成图片的那种(by Geodesic)
2012-5-17 ~ 2023-3-7
(0)
本程序实现将图片转换为 ascii 字符的效果。
使用说明:
支持 bmp / jpg / gif / emf / wmf / ico 类型的图片。gif 类型的图片仅加载第一帧,不支持透明。我只测试过jpg格式。
请把要转换的图片复制到 exe 程序所在的文件夹,并确保图片名中没有中文等无法输入的字符。
运行 exe 文件即可转换。
因为 txt 文件的行距,字符间距等原因,为了达到最好效果,请先把图片的高度压缩到原来的 1/2(宽度不变)。
转换根据图片的实际大小操作,如果图片过大,请修改图片尺寸,或者手工修改 txt 中字符的尺寸,以便能够完全显示。
这仅仅是一个 demo,里边存在不少问题,比如 ASCII 灰度实际上是按照 8*16 像素扫描的;实际使用的 ASCII 灰度值我修改过,并非原来的灰度等等。
为了更精确的控制字体的尺寸,间距,行距,html 文件是个不错的选择,如果你愿意的话,你可以选择完善这个 demo,做成一个很实用的小小的软件,但是让一个东西变得更加精致,并不是我的兴趣所在,所以估计今后我也不会再修改这个程序了。
为了方便你的完善,我给你写了一段灰度扫描的程序,有自己的 main(),可以独立的运行。
如果在本程序的基础上修改完善,请保留文件头部的作者信息
玩的开心o(∩_∩)o
执行效果如图:
以下是完整源代码:
/////////////////////////////////////////////////////
// 程序名称:图片转ASCII点阵demo
// 编译环境:Visual C++ 6.0,EasyX 2012-5-1测试版
// 作 者:Geodesic <Geodesicwl-cpro@yahoo.cn>
// 最后修改:2012-5-16
/////////////////////////////////////////////////////
//若提示缺少graphics.h(Easyx)头文件,请到这里下载:
//www.easyx.cn
/////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
/***********************宏定义***********************/
#define ASC_HEIGHT 8
#define ASC_WIDTH 8
#define ASCII_NUM 32
/*********************结构体定义*********************/
struct ascii
{
char asc[ASCII_NUM];
int gray[ASCII_NUM];
}as = {' ', '`', '.', '^', ',', ':', '~', '"', '<', '!', 'c', 't', '+', '{', 'i', '7', '?',
'u', '3', '0', 'p', 'w', '4', 'A', '8', 'D', 'X', '%', '#', 'H', 'W', 'M',
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};
/**********************函数声明***********************/
char SearchAsc(struct ascii as, int gray);
void Pic2Asc(struct ascii as, char filename[]);
/***********************主函数***********************/
int main(void)
{
char filename[256];
system("title, 图片转化为ASCII图画demo");
printf("请输入文件名(含扩展名)\n\n");
gets(filename);
system("cls");
Pic2Asc(as, filename);
printf("转换完成,任意键退出\n\n");
system("pause");
return 0;
}
/***********************函数体***********************/
//图片转化为ASCII点阵,并保存到txt和html文件中
void Pic2Asc(struct ascii as, char filename[])
{
int height, width, gray;
IMAGE img;
FILE *fpAscPicText;
//图像设备初始化
loadimage(&img, filename);
SetWorkingImage(&img);
height = getheight() / ASC_HEIGHT;
width = getwidth() / ASC_WIDTH;
if((fpAscPicText = fopen("ASC_PIC.txt", "w")) == NULL)
{
printf("文件打开失败\n");
exit(0);
}
//开始转化并保存结果
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
gray = 0;
//扫描每一小块的灰度,并计算出平均灰度
for(int h = 0; h < ASC_HEIGHT; h++)
for(int w = 0; w < ASC_WIDTH; w++)
{
gray += GetRValue(RGBtoGRAY(getpixel(j * ASC_WIDTH + w, i * ASC_HEIGHT + h)));
}
gray /= (ASC_HEIGHT * ASC_WIDTH);
gray = (255- gray) * 90 / 255;
fputc(SearchAsc(as, gray), fpAscPicText);
}
fputc('\n', fpAscPicText);
}
fclose(fpAscPicText);
}
//二分法查找ASCII字符,就低不就高
char SearchAsc(struct ascii as, int gray)
{
int lower = 0;
int higher = ASCII_NUM;
int mid;
if(gray <= as.gray[0])
{
return as.asc[0];
}
else if (gray >= as.gray[ASCII_NUM - 1])
{
return as.asc[ASCII_NUM - 1];
}
else
{
while((higher - lower) > 1)
{
mid = (lower + higher) >> 1;
if(gray > as.gray[mid])
{
lower = mid;
}
else
{
higher = mid;
}
}
return as.asc[lower];
}
}
作者:Geodesic
邮箱:geodesicwl-cpro@yahoo.cn
添加评论
取消回复