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,一经查实,立即删除!

相关文章

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

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

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

天下没有免费的午餐&#xff0c;如果有&#xff0c;那也是限时免费。不过&#xff0c;被地摊光盘浸淫十多年的中国民众&#xff0c;这次却对微软的免费分外冷淡。 就在7月26日这天&#xff0c;距离Windows 10免费升级还剩下最后三天&#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;深度学习的基本原理就是基于人工神经网络…

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

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

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

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

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

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

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

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

双时隙的工作原理_OFDM调制技术原理是什么 OFDM调制实现原理介绍【图文】

无线通讯OFDM调制技术原理简介OFDM是现代宽带无线通信系统应用的技术。为了减少高数据率OFDM系统中各信道间影响带来的失真&#xff0c;引入循环前缀(CP)来消除码间干扰(ISI)。它将一个IFFT包的最后部分复制到OFDM符号序列的前端。注意&#xff0c;CP的长度必须长于色散信道的长…

Windows 11 新版 22593 发布:文件资源管理器全新主页,开始菜单图标优化

面向 Dev 和 Beta 频道的 Windows 预览体验成员&#xff0c;微软现已发布 Windows 11 预览版 Build 22593。主要变化1.微软为 Windows 11 文件资源管理器引入了全新的主页功能&#xff0c;集成了快速访问、收藏夹和最近使用的文件。2.Windows 11 “开始”菜单文件夹中的应用程序…

2015年最弱的密码,和最强的密码

网络安全公司SplashData如约发布了本年度最不安全的密码排行榜。这是他们连续第五年做这件事了。 根据2015年从各个渠道泄露出来的密码信息&#xff0c;最弱的密码被“123456”再次蝉联。这个“万年陈酿”的密码排名第一感觉毫无压力。 夺得第二名的是“password”。中国用户似…

ideaspringboot项目上传服务器_nuxt+pm2 自动化部署及打包后文件自动上传阿里云 oss

在读这篇文档时&#xff0c;希望你对 nuxt 及 pm2&#xff0c;有简单的了解nuxtpm2前期准备安装 pm2 及构建 nuxt$ npm i pm2 -g $ npx create-nuxt-app <项目名>ssh 密钥配置pm2 代码自动发布依赖于 git 工具&#xff0c;先将 ssh 密钥配置再你的代码仓库&#xff08;gi…

wait放弃对象锁_Java线程中wait、await、sleep、yield、join用法总结

一、wait()、notify()、notifyAll()用法obj.wait()/obj.wait(long timeout)是Object中的方法&#xff0c;当线程调用wait()方法&#xff0c;当前线程释放对象锁&#xff0c;进入等待队列。obj.notify()/obj.nogifyAll()是Object中的方法&#xff0c;唤醒在此对象上wait()的单个…

怎么找到项目中所有同名的类_26岁转行程序员的成长历程--Day03从内存层面理解类和对象...

今天学习了类、对象及相关知识&#xff0c;试着从内存角度分析三者关系&#xff0c;如果有不对的地方请指正首先得先介绍java中的三个内存区域&#xff1a;栈区用于存放该线程执行方法的信息&#xff08;实际参数、局部变量等&#xff09;。栈属于线程私有&#xff0c;不能实现…

pycharm提示your evalluation license has expired解决方法

安装pycharm&#xff0c;一段时间后提示your evalluation license has expired&#xff1a;打开pycharm--点击help--register--选中license server,输入license server address如图示即可 转载于:https://www.cnblogs.com/youtiaoge/p/7125070.html

【SPSS统计分析】SPSS聚类分析:一个案例演示聚类分析全过程(附SPSS 19.0中文版下载)

摘要:案例数据源: 有20种12盎司啤酒成分和价格的数据,变量包括啤酒名称、热量、钠含量、酒精含量、价格。数据来自《SPSS for Windows 统计分析》。 目 录 问题一:选择那些变量进行聚类?——采用“R型聚类

python利用特征进行可视化样本显示_利用Python进行机器学习之特征选择

毫无疑问&#xff0c;解决一个问题最重要的是恰当选取特征、甚至创造特征的能力&#xff0c;这叫做特征选取和特征工程。对于特征选取工作&#xff0c;我个人认为分为两个方面&#xff1a;1)利用python中已有的算法进行特征选取。2)人为分析各个变量特征与目标值之间的关系&…

甘肃2019年9月计算机二级报名入口,2019年9月甘肃计算机二级考试成绩查询入口...

【摘要】2019年9月份计算机二级考试已经圆满结束&#xff0c;参加考试的小伙伴们已经迫不及待的想要知道成绩了吧&#xff0c;小编对2019年9月甘肃计算机二级考试成绩查询入口进行了整理&#xff0c;参加9月份考试的朋友们到时候记得按时查询成绩哦&#xff01;想要了解更多计算…

FluentEmail - 适用于 .NET 和 .NET Core 的邮件发送库

简介FluentEmail - 适用于 .NET 和 .NET Core 的邮件发送库从 .NET 和 .NET Core 发送电子邮件的最简单方法。将 Razor 用于电子邮件模板并使用 SendGrid、MailGun、SMTP 等进行发送Nuget包•FluentEmail.Core - 域模型•FluentEmail.Smtp - 通过 SMTP 服务器发送电子邮件•Flu…

安装MySql出现Error Nr.1045的解决办法

如图&#xff0c;最后一步出现这个错误框 这是因为上次安装过MySql&#xff0c;其用户数据在卸载的时候没有被删除掉&#xff0c;解决办法如下&#xff1a; 显示隐藏的文件夹&#xff0c;打开C盘&#xff0c;找到下图文件删除之 删除之后再安装一遍MySQL&#xff0c;就可以了转…