这篇文章主要介绍了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如何使用字符打印照片相关推荐

  1. python编辑视频字符化_Python 视频转字符画 - 进阶

    这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 0. 话说在前头 最新版使用了画布方式实现,和本文相比改动非常大,如果对旧版本的实现没啥兴趣,可以直接移步 vi ...

  2. python字符照片_python图片转字符图片

    python图片转字符图片代码 话不多说,直接上代码. *************************** #-*- coding:utf-8 -*- from PIL import Image ...

  3. python如何计算字符宽度_Python中计算字符宽度

    转载:http://likang.me/blog/2012/04/13/calculate-character-width-in-python/ 最近在用python写一个CLI小程序,其中涉及到计算 ...

  4. python视频转字符动画_Python 视频转字符动画 - 进阶

    这篇文章是 视频转字符动画-Python-60行代码 的后续,如果感兴趣,请先看看它. 0. 话说在前头 最新版使用了画布方式实现,和本文相比改动非常大,如果对旧版本的实现没啥兴趣,可以直接移步 vi ...

  5. python生成字符画_python生成动态字符画

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 但,可以将字符串的一部分复制到新创建的字符串,达到"看起来修改&quo ...

  6. python打印输出阶梯_python如何将字符阶梯型输出?

    以下代码用来实现阶梯型字符的输出: # Function to demonstrate printing pattern of alphabets def alphapat(n): # initial ...

  7. python生成中文字符画_Python 图片转字符画

    -- coding:utf-8 -- from PIL import Image import argparse 命令行输入参数处理 parser = argparse.ArgumentParser( ...

  8. python怎么打印图片_Python:使用字符打印照片

    最早的显示器是单色的,只能显示文本,每行最多显示80个字符.想看图片只能用针式打印机打印在两侧穿孔的宽行打印纸上,每个像素用一个字符表示,不同的字符代表不同的灰度,就像下图这个样子. 有没有感觉到浓郁 ...

  9. 怎么用python打印照片_Python综合应用:教你用字符打印一张怀旧风格的照片

    1. 前言 第一次在学校机房里见到计算机,还是上古时期.计算机型号大概是LASER-310吧,有点记不清了.那会儿,显示器还是单色的,只能显示文本,每行最多显示80个字符.想看图片,印象中只能用针式打 ...

最新文章

  1. 随机森林——气温预测(2/2)
  2. java redis使用卡死_记一次找因 redis 使用不当导致应用卡死 bug 的过程
  3. MySQL 用户创建及设置
  4. 康宁玻璃ct值计算公式_【钦州】CT室铅板生产厂家
  5. ecplise最有用的8个快捷键
  6. contes 7.6安装后网络问题解决方案
  7. linux进程线程协程的区别,进程和线程、协程的区别
  8. java剑指offer_剑指offer题目java实现
  9. C++对象池技术剖析
  10. Win10 安装 IE11 教程
  11. 『动态规划』矩阵连乘
  12. 计算机网络位置设置工作组,工作组设置【处置步骤】
  13. 产品经理全套入门学习资料,及各行业解析分享
  14. PC微信本地图片格式转化
  15. ubuntu 20.04 编译Android9.0的android源码
  16. 网络爬虫 | selenium 爬取动态加载信息
  17. pytorch--切断梯度的方法
  18. 音圈电机工作原理与直线电机的对比
  19. ffmpeg实战教程(十三)iJKPlayer源码简析
  20. OpenSBI ELF rela.dyn和.dynsym动态链接过程

热门文章

  1. Oracle 11g中的IO Calibrate(automatic DOP: skipped because of IO calibrate statistics are missing)
  2. Hack the box靶机 Chatterbox
  3. 第五人格周四服务器维护中,第五人格新监管者疯眼上线 将于每周四早上8:30进行停服维护...
  4. 说明:2023年工程系列职称评审对于论文发表的要求
  5. 利用MATLAB求解非线性优化问题---fgoalattain函数详解及应用案例
  6. odcl 转lisp_AUTOLISP编程心得_2.pdf
  7. 【全栈】vue3.0 + golang 尝试前后端分离【博客系统1.0】开发
  8. linux中配置搜狗输入法
  9. 达梦dsc集群节点在线扩容
  10. Java后台处理标点符号转义