python字符照片_Python如何使用字符打印照片
这篇文章主要介绍了Python如何使用字符打印照片,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
1. 前言
第一次在学校机房里见到计算机,还是上古时期。计算机型号大概是LASER-310吧,有点记不清了。那会儿,显示器还是单色的,只能显示文本,每行最多显示80个字符。想看图片,印象中只能用针式打印机打印在两侧穿孔的宽行打印纸上,每个像素用一个字符表示,不同的字符代表不同的灰度,就像下图这个样子。有没有感觉到浓郁古风呢?其实,随便一张照片,十几行Python代码,你也可以打印出这样的效果,还可以保存成文件。下面,我就一步一步地演示一下。
2. 打开图片,转为灰度模式
Python用于图像处理的模块有很多,最常用的当属PIL和PyOpenCV了。本案使用PIL模块来打开图像:
>>> from PIL import Image
>>> im = Image.open('xufive.jpg')
>>> im.size
(979, 1248)
>>> im.mode
'RGB'
im就是打开的图像对象,im.size是图像的分辨率,im.mode是图像模式。我们知道,计算机图像有很多种颜色模式,RGB是最常见的彩色图像模式。打印字符图片的话,需要将RGB模式转为灰度模式:
>>> im = im.convert('L')
>>> im.mode
'L'
3. 改变分辨率
打印字符图片,需要考虑显示器每行显示的字符个数。假定屏幕水平分辨率为1920,每个字符宽度占8个像素,每行可以显示240个字符。综合考量,我们设定每行显示120个字符。这就需要我们将灰度图片的宽度设置为120个像素,那么图像高度的像素数height应为:
width = 120
height = int(width*im.size[1]/im.size[0])
按照新的分辨率生成图像对象:
>>> im = im.resize((width, height))
>>> im.size
(120, 152)
4. 反白处理
灰度模式下,每个像素的值域范围是0~255,共有256级灰度。考虑到屏幕背景色可能是深色的,也可能是浅色的,我们需要提供图像反白处理的手段。所谓反白处理,就是用灰度最大值255减去每一个像素的灰度值作为该像素新的灰度值。遍历每一个像素,固然可以实现反白,但速度会很慢。本案使用NumPy数组的广播技术,可以显著提升处理速度。我们先把PIL图像对象转成NumPy数组:
>>> import numpy as np
>>> arr = np.array(im)
>>> arr.shape
(152, 120)
>>> arr.dtype
dtype('uint8')
需要特别说明的是,PIL对象的图像分辨率是120x152,表示图像宽度120像素,高度152像素;转成NumPy数组之后,数组的shape则是(152,120),表示图像有152行(对应高度),120列(对应宽度)。虽然PIL对象和NumPy数组关于行列的概念不一致,但表达的物理意义是相同的。
利用NumPy数组的广播技术实现反白处理,只需一行代码,并且瞬间完成:
arr = 255 - arr
5. 确定灰度-字符映射表
在显示器上,字符是由点阵组成的。每个字符的亮点(或暗点)不同,可以用来表示不同的灰度。本案使用了下面8个字符表示不同的灰度:
>>> chs = np.array([' ', '.', '-', '+', '=', '*', '#', '@'])
>>> chs.dtype
dtype('
8个不同的字符,只能表示8级灰度,因此需要将像素的256级灰度值转换为8级:
>>> arr = arr/32
>>> arr = arr.astype(np.uint8)
>>> arr.min(), arr.max()
(0, 7)
6. 灰度转字符
接下来需要将值域范围在0~7之间的每一个像素转为灰度-字符映射表中对应的字符。同样的,我们可以用两层嵌套的循环结构来完成,不过更好的选择是用NumPy数组的矢量化特性来实现。本例展示了NumPy数组非常少见的一种应用方式,我很少见到有人这样应用。
>>> arr = chs[arr]
>>> arr.shape
(152, 120)
>>> arr.dtype
dtype('
7. 打印
有了上述铺垫,打印自然是水到渠成了:
>>> for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
print(arr[i,j], end='')
print()
8. 保存为文件
如果在显示终端上打印不方便观看的话,还可以将字符数据保存成文件:
>>> with open('xufive.txt', 'w') as fp:
for line in arr.tolist():
fp.write(''.join(line))
fp.write('\n')
下图是输出到文本文件,在编辑器中显示的效果。
9. 完整代码
在不同的运行环境中,最终图像显示的宽高比和原图会有差异。为了抵消差异,我在下面的代码中增加了一个矫正系数k,可以通过调整这个参数,获得满意的显示效果。
# -*- coding: utf-8 -*-
from PIL import Image
import numpy as np
def print_photo(photo_file, width=120, k=1.0, reverse=False, outfile=None):
"""打印照片,默认120个字符宽度"""
im = Image.open(photo_file).convert('L') # 打开图片文件,转为灰度格式
height = int(k*width*im.size[1]/im.size[0]) # 打印图像高度,k为矫正系数,用于矫正不同终端环境像素宽高比
arr = np.array(im.resize((width, height ))) # 转为NumPy数组
if reverse: # 反色处理
arr = 255 - arr
chs = np.array([' ', '.', '-', '+', '=', '*', '#', '@']) #灰度-字符映射表
arr= chs[(arr/32).astype(np.uint8)] # 灰度转为对应字符
if outfile:
with open(outfile, 'w') as fp:
for row in arr.tolist():
fp.write(''.join(row))
fp.write('\n')
else:
for i in range(arr.shape[0]): # 逐像素打印
for j in range(arr.shape[1]):
print(arr[i,j], end=' ')
print()
if __name__ == '__main__':
print_photo('xufive.jpg', width=360, k=0.5, outfile='xufive.txt')
下图是在命令行窗口显示的效果。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持python博客。
python字符照片_Python如何使用字符打印照片相关推荐
- python编辑视频字符化_Python 视频转字符画 - 进阶
这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 0. 话说在前头 最新版使用了画布方式实现,和本文相比改动非常大,如果对旧版本的实现没啥兴趣,可以直接移步 vi ...
- python字符照片_python图片转字符图片
python图片转字符图片代码 话不多说,直接上代码. *************************** #-*- coding:utf-8 -*- from PIL import Image ...
- python如何计算字符宽度_Python中计算字符宽度
转载:http://likang.me/blog/2012/04/13/calculate-character-width-in-python/ 最近在用python写一个CLI小程序,其中涉及到计算 ...
- python视频转字符动画_Python 视频转字符动画 - 进阶
这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 0. 话说在前头 最新版使用了画布方式实现,和本文相比改动非常大,如果对旧版本的实现没啥兴趣,可以直接移步 vi ...
- python生成字符画_python生成动态字符画
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 但,可以将字符串的一部分复制到新创建的字符串,达到"看起来修改&quo ...
- python打印输出阶梯_python如何将字符阶梯型输出?
以下代码用来实现阶梯型字符的输出: # Function to demonstrate printing pattern of alphabets def alphapat(n): # initial ...
- python生成中文字符画_Python 图片转字符画
-- coding:utf-8 -- from PIL import Image import argparse 命令行输入参数处理 parser = argparse.ArgumentParser( ...
- python怎么打印图片_Python:使用字符打印照片
最早的显示器是单色的,只能显示文本,每行最多显示80个字符.想看图片只能用针式打印机打印在两侧穿孔的宽行打印纸上,每个像素用一个字符表示,不同的字符代表不同的灰度,就像下图这个样子. 有没有感觉到浓郁 ...
- 怎么用python打印照片_Python综合应用:教你用字符打印一张怀旧风格的照片
1. 前言 第一次在学校机房里见到计算机,还是上古时期.计算机型号大概是LASER-310吧,有点记不清了.那会儿,显示器还是单色的,只能显示文本,每行最多显示80个字符.想看图片,印象中只能用针式打 ...
最新文章
- 随机森林——气温预测(2/2)
- java redis使用卡死_记一次找因 redis 使用不当导致应用卡死 bug 的过程
- MySQL 用户创建及设置
- 康宁玻璃ct值计算公式_【钦州】CT室铅板生产厂家
- ecplise最有用的8个快捷键
- contes 7.6安装后网络问题解决方案
- linux进程线程协程的区别,进程和线程、协程的区别
- java剑指offer_剑指offer题目java实现
- C++对象池技术剖析
- Win10 安装 IE11 教程
- 『动态规划』矩阵连乘
- 计算机网络位置设置工作组,工作组设置【处置步骤】
- 产品经理全套入门学习资料,及各行业解析分享
- PC微信本地图片格式转化
- ubuntu 20.04 编译Android9.0的android源码
- 网络爬虫 | selenium 爬取动态加载信息
- pytorch--切断梯度的方法
- 音圈电机工作原理与直线电机的对比
- ffmpeg实战教程(十三)iJKPlayer源码简析
- OpenSBI ELF rela.dyn和.dynsym动态链接过程
热门文章
- Oracle 11g中的IO Calibrate(automatic DOP: skipped because of IO calibrate statistics are missing)
- Hack the box靶机 Chatterbox
- 第五人格周四服务器维护中,第五人格新监管者疯眼上线 将于每周四早上8:30进行停服维护...
- 说明:2023年工程系列职称评审对于论文发表的要求
- 利用MATLAB求解非线性优化问题---fgoalattain函数详解及应用案例
- odcl 转lisp_AUTOLISP编程心得_2.pdf
- 【全栈】vue3.0 + golang 尝试前后端分离【博客系统1.0】开发
- linux中配置搜狗输入法
- 达梦dsc集群节点在线扩容
- Java后台处理标点符号转义