将图片转为ASCII字符画

时间:2021-01-30 18:19:35

原文:将图片转为ASCII字符画

Copyright 2012 Conmajia

源代码下载:点击这里

什么是字符画?就是用ASCII字符来近似组成图像,就像这样:

  ╭╮       ╭╮  
 ││       ││  
╭┴┴———————┴┴╮
│           │   
│           │   
│ ●       ● │
│○  ╰┬┬┬╯  ○│
│    ╰—╯    │ 
╰——┬O———O┬——╯
   ╭╮    ╭╮    
   ╰┴————┴╯

还有复杂点的:

﹎ ┈ ┈ .o┈ ﹎  ﹎.. ○
﹎┈﹎ ● ○ .﹎ ﹎o▂▃▅▆
┈ ┈ /█\/▓\ ﹎ ┈ ﹎﹎ ┈ ﹎
▅▆▇█████▇▆▅▃▂┈﹎
                    .----.
_.'__ `.
.--(#)(##)---/#\
.' @ /###\
: , #####
`-..__.-' _.-\###/
`;_: `"'
.'"""""`.
/, 野比 ,\
// 很穷! \\
`-._______.-'
___`. | .'___
(______|______)

今天要做的就是把一副图片(卡通动画,照片)转换成类似这样的效果。

相信很多人都做过,我这里就简单提一下。

基本思想就是用不同“亮度”的字符(每个字符有自己对应的视觉亮度)替换图片中对应亮度的那些部分,最后形成和原图亮度分布差不多的“看起来很像”的字符画。
核心代码很简单,不到50行。为了图方便我没有把原图切块后的Blob保存下来,这个供大家自行发挥。
注意其中用到了FastBitmap,这个增强Bitmap类以前我发的代码里也有,用来稍微加快下处理速度。如果觉得不方便,直接删除带有「fast」的语句就可以,不用做其他修改。

 public static string Generate(Bitmap img, int rowSz, int colSz)
{
StringBuilder sb
= new StringBuilder(
img.Width / colSz * img.Height / rowSz
);
FastBitmap fast
= new FastBitmap(
img
); fast.Lock();
for (int h = ; h < img.Height / rowSz; h++)
{
int yoffset = h * rowSz;
for (int w = ; w < img.Width / colSz; w++)
{
int xoffset = w * colSz;
int br = ; for (int y = ; y < ; y++)
for (int x = ; x < ; x++)
try
{
Color c = fast.GetPixel(
x + xoffset,
y + yoffset);
br =
br + (int)(c.GetBrightness() * );
}
catch
br += ;
br /= ;
if (br / < charset.Length)
sb.Append(
charset[br / ]);
else
sb.Append(' ');
}
sb.AppendLine();
}
fast.Unlock(); return sb.ToString();
}

其实最关键部分在于使用的调色盘,转换结果好不好,全靠Palette。不过由于时间关系,我随便弄了个对付对付。。
使用程序时先Load图片(注意别太大,如果太大,需要增大w和h来减少分块数量,否则会很慢)。然后设定好分块大小(单个块),最后点击「Generate」按钮。程序会在桌面上生成一个临时文件(HTML格式),并在浏览器中打开文件,供你查看结果。

将图片转为ASCII字符画

下面是转换效果(可以看到糟糕的调色盘配置)

将图片转为ASCII字符画

网上老外还有做成支持彩色的字符画,也是基于HTML表示,基本原理和这个差不多,各位可以自己玩玩看。。

你甚至还可以做成动画,就像这样。你懂的。

将图片转为ASCII字符画

(完)

Copyright 2012 Conmajia