c#字符型转化为asc_关于图片转抽象字符画以及一些问题

74fce36ec699ecf4d4f3593b877487d8.png

有很多用字符表示动作、表情的例子,比如

——————/´ ¯/)
—————--/—-/
—————-/—-/
———--/´¯/'--'/´¯`·_
———-/'/--/—-/—--/¨¯
——--('(———- ¯~/'--')
———————-'—--/
———-''————_-·´
———————--(
————-———--

用代码实现起来很简单。

比如首先用画图画一个歪瓜裂枣的心形,然后掏出油漆桶上色。

d7397b8b8275846f33cc6c57e8ce5abd.png

然后保存,假设文件名是"kkr.png"。

把这张图转换成字符的一种思路如下:

首先读入图片转换为灰度图,然后根据灰度在相应位置选取合适的字符替换(记得换行),最后把总的字符集输出或者写入文件。

但是还有一些细节上的问题。比如图片的尺寸。一个1080*1080的图片难道每行1080个字符吗?这样肯定屏幕上放不下,看起来效果非常差。首先想到的一种解决方法就是缩放,常见的图像库肯定提供这个功能。当然,也有其他思路。比如在神经网络里处理图像时,面对图像信息过多的问题是,使用了卷积神经网络,这里同样可以选用恰当的卷积核进行卷积、池化操作。不过这样其实和缩放差不多(缩放还能更容易保证不失真)。

比如python代码实现:

from PIL import Image

fp=open('kkr.png','rb')
img=Image.open(fp)
img=img.convert("L")
w,h=img.size
k=0.05
img=img.resize((int(k*w),int(k*h)))
w,h=img.size

string=""
for i in range(h):
    for j in range(w):
        gray=img.getpixel((j,i))
        asc=int(gray/255*93)+33
        string+=chr(asc)
    string+='n'

out=open('out.txt','w')
out.write(string)
out.close()
fp.close()

我的代码里关于灰度和字符的对应是这样选取的:灰度的值为0-255的整数,我选取字符的ASCII码在33-126,然后在[0,255]和[33,126]之间建立均匀的线性映射。

k为缩放比,缩小为原图的0.05倍。

结果如下

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~BBBB~~~~~~~~
~~~~~~~~~~~~~~~BBB~~BBBBBB~~~~~~~
~~~~~~~~~~~~~~BBBBB~BBBBBB~~~~~~~
~~~~~~~~~~~~~BBBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~BBBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~BBBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~BBBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~~BBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~~BBBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~~~BBBBBBBBBBB~~~~~~~
~~~~~~~~~~~~~~~!BBBBBBBBB~~~~~~~~
~~~~~~~~~~~~~~~~~BBBBBBB~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这个结果可以看出一个问题:比例失调了。

原因很简单:字符的宽度和高度不相等,再加上行间距和字符间距不相等。

如果在缩放时把图像合理拉宽,或者在word里把这些东西调好之后观察,就可以出现比较好的效果。

如果继续尝试还会发现更多问题。

比如这个算法只适用于背景灰度几乎一致的简单图形,比如如下的结果:

C=D?=<>6B9B77523?451/
<>C>MBD=N8:6198956<'F
<A@;.>FPT97F@=569DF:<
>;=>9C5?DJ`OACU1K:5?
?UGGXYYsXSY]TE?<85D
PR[X`bUdh_UX5C4>17:6
]Z^gaQZZ_QPa_=AW@B9Q
b`^Zh_PnZ^fGUDWAR:A1
aX^ca`ead]jpc@D@B>DG>
]Y_`d]hmgmQWD?NDEB@^
ke_d_bgxslCK>BF?P9_.7
]hfdchjqtQh=ACH;8P@L7
`uic_ndduE?E;3@B3HA=K
ellu|ybSi<7AC*6MT:@6
d_bp{yDHcc.9CJ?CB576?
_Y]ahoH;L@9<>3qL:8B-<
^_`^]A:=4JEBLTFNRJC.
@JoOTNA>DAMELROQ@EH
ME@6VavpZUaP>S^^J?H>
F<7LJ=[NITLO`TXTN178Y
RUMQQSTTCRU[]d`_AA>Q

不妨猜一下这是什么玩意。

谁能猜出来这其实是一只可爱的橘猫?

不过如果对代码稍加改动:

asc=int(gray/255*93)+33 if gray>150 else ord(' ')

其实就是加了个阈值,灰度不超过150的部分用空格替换。

结果是:


`
XYYsX Y]
[X`b dh_ X
]Z^ga ZZ_ a_
b`^Zh_ nZ^f
aX^ca`ead]jpc
]Y_`d]hmgm ^
ke_d_bgxsl _
]hfdchjqt h
`uic_nddu
ellu|yb i
d_bp{y cc
_Y]aho q
^_`^]
o
avpZ a ^^
[ ` X Y
[]d`_

还是能勉强看(naobu)出来有只猫的轮廓的。

针对这种问题,可以考虑的一种解决方法是:不转化为灰度图,直接用rgb图的信息来处理(毕竟这种图转换成灰度图已经看不清了)。然后针对颜色划分类别(比如把色环切分成若干块),每一类是相似的颜色并且对应同一个字符,能够在拓扑信息上较好地还原图像,也就能“看”出原图的效果。

掌握了这个方法就可以自制表情包,此外,也可以用此方法装饰自己的steam自定义信息框展柜。在展柜里放上沙雕表情包或者二次元老婆(划掉)来吸引同好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值