char添加一个字符_给你五十行代码把图片变成字符画!程序:太多了,一半都用不完...

67f37192c8a9b816261dd956319ef68b.png

今天和大家分享一个简单又好玩的Python项目–“图片转字符画”。废话不多说,先上一个效果图迷惑一下众生。

ed3d79e453a05f9738fff8d0ef03dfca.png

没错的,图片转字符画就是将我们平常所看到的的图片根据像素RGB值和灰度值传化成一个个字符串的过程。

嗯…听起来有些费脑子喔。没关系,且听小五为小伙伴一一分解。

像素RGB值

什么是像素RGB值?

其实就像我们平常所看到的所有图片,无论是彩色照还是黑白照,其实它们都是有色彩的,更加神奇的是,我们肉眼所看到的所有色彩几乎都是由红(Red)、绿(Green)、蓝(Blue)经过不同深度的调色后得到的。

而RGB色彩模式就是是工业界的一种颜色标准,是通过对红®、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的。

所以RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

88c99f343920ccf26dae1bc4a3d3e65f.png

所以也可以说,我们所看到的所有具有色彩的图片都是由这三种颜色调出来的。

而对于字符画,顾名思义是一系列字符的组合,我们可以把字符看作是比较大块的像素,一个字符能表现一种颜色。

就像我们刚才所看到的那张图片转成字符画之后,画中包含着各种不同层次的字符,所以字符的种类越多,可以表现的颜色也越多,图片也会更有层次感。

那么小伙伴们可能就会问了,我们是要转换一张彩色的图片,这么多的颜色,要怎么对应到只有一种颜色而且还包括那么多字符的的字符画上去?

哈哈,不知道了吧?这里就要介绍灰度值的概念了。来来来,科普一下!

1ab74f5e4e47b32e28c283741f4b4b97.png

灰度值计算

灰度值:指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0,故黑白图片也称灰度图像。

所以我们可以使用灰度值公式将像素的 RGB 值映射到灰度值,也就是下面这个公式:(注意这个公式是简化过的,真正的计算公式会复杂些)

灰度值计算公式
gray = 0.2126 * r + 0.7152 * g + 0.0722 * b

这样就好办了,我们可以创建一个不重复的字符列表,然后用每一个字符表示一种颜色,灰度值小(暗)的用列表开头的符号表示,灰度值大(亮)的用列表末尾的符号表示。

注意!重点来了!敲黑板!!!

e3f5b32be8559a8e296ab1c3dabd02db.png

我们知道。单从黑色到白色,颜色深度的范围就是0-255,也就是说这一共有256个不同深浅的颜色,那我们如果想要将每一种颜色以不同的字符表示出来,那岂不是需要256个不同的字符嘛?

哈哈,我觉得也是,去找256个不同的字符写的你的程序里面组成一个字符串,想想都刺激,但是你会去这么做嘛?我想不会吧?

所以我们只需要想一种办法,让颜色深度相近的灰度值用不同的符号表示即可,所以我们可以定义一个存放不同字符的字符串,用来表示不同的色彩的字符。在这里定义的这个字符串的长度是70。

定义代表灰度的字符
ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ") #设置显示的字符集

灰度值映射字符函数

之后我们只需要定义一个函数,将我们需要转化成字符画的图片的每一个像素找到与其相对应的字符并返回即可。

该函数如下,传入的参数是图片上某一点处的像素值,同时还有一个透明度参数:

将256灰度映射到70个字符上
def get_char(r,g,b,alpha = 256):
#alpha为透明度
# 判断 alpha 值,为0表示全透明
if alpha == 0:
return ' '
# 获取字符集的长度,这里为 70
length = len(ascii_char)
# 将 RGB 值转为灰度值 gray,灰度值范围为 0-255
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
# 灰度值范围为 0-255,而字符集只有 70
# 需要进行如下处理才能将灰度值映射到指定的字符上
#防止当灰度值为255时,输出的第70个字符超出列表索引,所以需要将(255+1)
unit = (255.0 + 1)/length
# 返回灰度值对应的字符
return ascii_char[int(gray/unit)]

当我们写好像素映射字符串的函数方法之后,我们就可以对不同的像素获取到不同的字符表示了。

0f6b8fe07ca0075d744167536a1dd53f.png

图片导入及尺寸设置

那么接下来就是我们应该如何获取图片上某一点处的像素了。这个时候我们需要调用pillow库,这个库的作用就是对图片进行基本的处理。

在这里我们需要使用的是pillow库下的Image类,使用Image下的resize方法,我们可以对图片进行缩放,并设置输出的图片质量。

以下面这张图片为例:

a96dc369a9f7f916d6a27ccab51880f9.png

进行图片缩放和输出质量设置

IMG = 't01b2a945701805d7f1.jpg' #设置图片文件
WIDTH = 150 #设置字符画的宽
HEIGHT = 80 #设置字符画的高
im = Image.open(IMG)
im = im.resize((WIDTH,HEIGHT), Image.NEAREST)

遍历图片获取字符

之后可以调用Image.getpixel()方法,给其传入坐标参数就可以返回该坐标处的像素值,值得注意的地方是,如果这个坐标处的像素是具有透明属性的。

那么还会返回alpha透明度参数,这就是为什么我们在映射字符串函数方法的参数中传入透明度参数并进行判断的原因。

将 (j,i) 坐标的 RGB 像素转为字符后添加到 txt 字符串
txt += get_char(*im.getpixel((j,i)))

现在我们要做的就是对该尺寸的图片进行横向和纵向的坐标遍历,获取到每一个坐标点处映射的字符,并将其在存储在我们设定的存放图片字符串的列表中即可。

遍历图片中的每一行
for i in range(HEIGHT):
# 遍历该行中的每一列
for j in range(WIDTH):
# 将 (j,i) 坐标的 RGB 像素转为字符后添加到 txt 字符串
txt += get_char(*im.getpixel((j,i)))
# 遍历完一行后需要增加换行符
txt += 'n'

字符画输出和导入文件

最后将该字符列表在屏幕输出或者存放到文本文件中,为了可以更好的看到字符画的效果,在这里大灰狼建议将该字符列表存放到一个文本文件中。

导入文件
OUTPUT = 'output5.txt' #设置存放字符画的文本文件
#保存到文本文件
with open(OUTPUT,'w') as f:
f.write(txt)

将图片转字符画处理后保存在文本文件中,我们可以在文本文件中找到被字符化后的照片了。

30556e1ca6f091ef1ec2a47aea927b07.png

好了,到这里图片转字符画的过程就基本结束了。

除去注释最后不到25行,使用的小伙伴只需要将程序最上面的图片路径修改成自己的图片即可!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android之You need to use a Theme.AppCompat theme (or descendant) with this activity.

1 问题 点击activity的时候,崩溃日志如下 You need to use a Theme.AppCompat theme (or descendant) with this activity. 2 原因 我类的activity是继承了有主题的activity,但是我在AndroidManifest.xml文件里面声明这个类的时候设置的主题如下 android:theme"android…

oom 如何避免 高并发_微博短视频百万级高可用、高并发架构如何设计?

本文从设计及服务可用性方面&#xff0c;详细解析了微博短视频高可用、高并发架构设计中的问题与解决方案。今天与大家分享的是微博短视频业务的高并发架构&#xff0c;具体内容分为如下三个方面&#xff1a;团队介绍微博视频业务场景“微博故事”业务场景架构设计团队介绍我们…

免费都不管用,Win10升级在中国怎么就这么难?

天下没有免费的午餐&#xff0c;如果有&#xff0c;那也是限时免费。不过&#xff0c;被地摊光盘浸淫十多年的中国民众&#xff0c;这次却对微软的免费分外冷淡。 就在7月26日这天&#xff0c;距离Windows 10免费升级还剩下最后三天&#xff0c;微软发了一份怨念深重的声明——…

IDL中生成等差/等比数列的方法

等差数列: 生成差值为5,

计算机病毒是指______.,计算机病毒是指

语音内容&#xff1a;大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。计算机病毒是编制者在计算机程序中插入的破坏计算机功能或者数据的代码&#xff0c;能影响计算机使用&#xff0c;能自我复制的一组计算机指令或者程序代码。电…

在非k8s 环境下 的应用 使用 Dapr Sidekick for .NET

在k8s 环境下&#xff0c;通过Operator 可以管理Dapr sidecar&#xff0c; 在虚拟机环境下&#xff0c;我们也是非常需要这样的一个管理组件&#xff0c;之前写的一篇文章《 在 k8s 以外的分布式环境中使用 Dapr》 里面介绍了一个案例Dapr case study: Man Group&#xff1a;ht…

sigmoid函数_常用的激活(激励)函数——深度学习笔记(建议收藏)

激活函数(又叫激励函数&#xff0c;后面就全部统称为激活函数)是模型整个结构中的非线性扭曲力&#xff0c;神经网络的每层都会有一个激活函数。那他到底是什么&#xff0c;有什么作用&#xff1f;都有哪些常见的激活函数呢&#xff1f;深度学习的基本原理就是基于人工神经网络…

LINUX - /etc/init.d/nginx: line 51: kill: (29833) - No such process

rootgosstech-All-Series:/home# service nginx stopStopping nginx daemon: /etc/init.d/nginx: line 51: kill: (29833) - No such process 以上是报错&#xff1b; 没有进程了&#xff1b;多半是关机不当&#xff1b;比如断电等&#xff1b; 解觉方法&#xff1a;cd /usr/lo…

Android之屏幕旋转之后当前activity被finish了依然被拉起来

1 问题 屏幕旋转之后当前activity被finish了依然被拉起来 2 分析思路 不用finish函数,使用 android.os.Process.killProcess(android.os.Process.myPid()); 还是被拉起来了,然后采用 System.exit(0); 还是被拉起来了,然后我就看app的进程,有2个进程,当一个activity被finish…

IDL与C#混合编程技术

C# (C Sharp)是微软公司在2000年6月发布的一种新的编程语言。C#与Java有很多的相似

0330Cache Buffers chains与共享模式疑问

[20150330]Cache Buffers chains与共享模式疑问.txt --昨天我看了链接http://blog.itpub.net/22034023/viewspace-708296/,重复测试,无法再现,我修改一下测试方法: 1.建立测试环境: SCOTTtest> ver1 PORT_STRING VERSION BANNER ----------------…

计算机导论上机模拟,计算机导论模拟考试题6份完整版.doc

计算机技术导论模拟考试题第三次模拟考试题1判断题(5). 接口是外部设备和CPU之间的信息中转站。(7). 嵌入式系统CPU大部分采用冯.诺依曼体系结构。(10). Excel工作表的名称由文件名决定。(11). 一个关系只能有一个主键。(12). 关系中元组的次序是任意的。(13). 在关系中能唯一区…

java如何进行字符串拼接?

将字符串数组中的字符串拼接成一个字符串&#xff0c;中间以“,”分割&#xff1b; example&#xff1a; String[] str{"John","lily,","lily","lucy"}; String objectStr""; for(int i0;i<str.length;i){if(i!str.lengt…

江苏信息考试access_软考 信息处理技术员备考复习攻略

如何备考信息技术处理员&#xff1f;在上午题和下午题中哪些知识点是重点难点&#xff1f;以下整理了信息处理技术员相关信息&#xff0c;祝所有考生们都能顺利通过考试。1上午考试试题分析上午试题含盖了纲中的信息技术基本概念、信息处理技术知识、计算机系统基础知识、操作系…

.NET6之MiniAPI(三十):结束篇(附链接)

不知不觉来到了《.NET6之MiniAPI》的第三十篇&#xff0c;回顾之前的篇幅&#xff0c;主要涉及如下&#xff1a;HTTP请求&#xff0c;应答Request桂素伟&#xff0c;公众号&#xff1a;桂迹.NET6之MiniAPI(二)&#xff1a;requestResponse桂素伟&#xff0c;公众号&#xff1a;…

Servlet生命周期中的service方法分析

问题ServletLifeCycle中的service方法内,有super.service(request, response); 会执行this.doGet(HttpServletRequest request, HttpServletResponse response);没有super.service(request, response);,则不执行this.doGet(...). 是怎么实现的? 举一反三:一个子类,覆写的方法内…

linux之ubunt把启动栏底部和左边切换

1 把启动栏移动到底部 gsettings set com.canonical.Unity.Launcher launcher-position Bottom 2 把启动栏移动到左边 gsettings set com.canonical.Unity.Launcher launcher-position Left

xhr get获取文件流下载文件_python爬虫实战——豆瓣电影get初体验

影评许可证公众号[2019]第22期本栏目由“数据皮皮侠”独家呈献专场python爬虫实战——豆瓣电影get初体验2019.10.28 / 早上7点场 / 免费本期“栏目”的四大看点&#xff1a;1 如何爬取2 如何解析与提取3 如何解析json数据4 实战&#xff1a;爬取豆瓣影视信息1 如何爬取how to O…

Visual Studio与C#编程十个实用技巧

如果你通过搜索引擎发现这篇文章的,我建议你先看看本系列的 第一篇 ,这是本系列文章的第二篇,今天为大家带来更丰富的C#和Visual Studio编程技巧,一起来看看吧。 1、DataTable.HasRows 它不属于任何框架,但通过扩展方法很容易模仿这样一个方法,它不会消除检查数据表对象…

商丘高中计算机考试成绩查询系统,2019商丘中考招生成绩查询时间及网站公布...

成绩发布&#xff1a;今年中招成绩满分仍为700分。7月8日&#xff0c;公布中招成绩。考生可以通过“商丘便民网”及手机APP客户端进行查询&#xff0c;也可以登陆省中招平台(http&#xff1a;//zk.haedu.gov.cn)和商丘市基础教育公共服务平台(http&#xff1a;//www.sqsedu.net…