python-图片之乐-ASCII 文本图形

news2024/11/20 20:29:41

ASCII:一个简单的字符编码方案

pillow模块:读取图像,访问底层数据
numpy模块:计算平均值

import sys, random, argparse
import numpy as np
import math
from PIL import Image

定义灰度等级和网格

定义两种灰度等级作为全局值,用于将亮度值转换为ASCII 字符

从最黑暗变到最亮

# 70 levels of gray
gscale1 = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "

# 10 levels of gray
gscale2 = '@%#*+=-:. '

http://paulbourke.net/dataformats/asciiart/

准备图像,并分割成网格

cols = 80
scale = 0.43

# open the image and convert to grayscale
image = Image.open('youling.png').convert("L")
# store the image dimensions  # image.size
W, H = image.size[0], image.size[1]
# compute the tile width  根据用户给定列数(cols)计算每个网格的宽度
w = W/cols
# compute the tile height based on the aspect ratio and scale of the font
h = w/scale
# compute the number of rows to use in the final grid
rows = int(H/h)

w网格的宽 = W图片的宽 / cols列数
h网格的高度 = w网格的宽 / 垂直比例系数scale
rows行 总共有多少行

Pillow模块里的convert()函数可以将图像从一种模式转换为另一种模式
convert(‘L’)将原始图像转换为灰度图像 L is luminance:是图像亮度的单位
convert(‘1’)将原始图像转换为黑白模式
convert(‘P’, palette=Image.ADAPTIVE, colors=1)将原始图像转换为使用颜色调色板的单色模式,colors=2,图片只有2种颜色
还有RGB、RGBA,CMYK,LAB,HSV,YCbCr、XYZ等等模式

CMYK代表青、洋红、黄和黑色,是一种用于印刷的颜色模式。它是印刷过程中使用的四种油墨颜色的缩写,包括青色(Cyan)、洋红色(Magenta)、黄色(Yellow)和黑色(Key),通过它们的不同组合可以得到各种颜色和色调。相对于RGB颜色模式(红、绿、蓝),CMYK颜色模式更适合印刷。

计算平均亮度

计算灰度图像中每一小块的平均亮度

def getAverageL(image):
    # get the image as a numpy array
    im = np.array(image)
    # get the dimensions
    w,h = im.shape
    # get the average
    return np.average(im.reshape(w*h))

将 image 转换成一个 numpy数组,此时 im 成为一个二维数组,包含每个像素的亮度

保存该图像的尺寸

numpy.average()计算该图像中的亮度平均值,做法是用 numpy.reshape()先将维度为宽和高(w,h)的二维数组转换成扁平的一维,其长度是宽度乘以高度(w*h)。然后 numpy.average()调用对这些数组值求和并计算平均值

从图像生成 ASCII 内容

在这里插入图片描述

# an ASCII image is a list of character strings
aimg = []
# generate the list of tile dimensions
for j in range(rows):
    # 计算每个图像小块的起始和结束 y 坐标
    y1 = int(j*h)
    y2 = int((j+1)*h)
    # correct the last tile
    if j == rows-1:
        y2 = H
    # append an empty string
    aimg.append("")
    for i in range(cols):
        # crop the image to fit the tile
        x1 = int(i*w)
        x2 = int((i+1)*w)
        # correct the last tile
        if i == cols-1:
            x2 = W
        # crop the image to extract the tile into another Image object
        img = image.crop((x1, y1, x2, y2))
        # get the average luminance # 获取网格的平均亮度值
        avg = int(getAverageL(img))
        # look up the ASCII character for grayscale value (avg)
        if moreLevels:
	        # 将平均亮度值[0,255]对用到70级灰度[0,69]
	        gsval = gscale1[int((avg*69)/255)]
	    else:
	        # 将平均亮度值[0,255]对用到10级灰度[0,9]
	        gsval = gscale2[int((avg*9)/255)]
        # append the ASCII character to the string
        aimg[j] += gsval

int((avg69)/255)
if avg = 255,可得int((avg
69)/255)=69,在该字符串中最后一个索引是69
在这里插入图片描述

命令行选项

接下来,为程序定义一些命令行选项。这段代码使用内置的 argparse 类:

parser = argparse.ArgumentParser(description="descStr")
# add expected arguments
parser.add_argument('--file', dest='imgFile', required=True)
parser.add_argument('--scale', dest='scale', required=False)
parser.add_argument('--out', dest='outFile', required=False)
parser.add_argument('--cols', dest='cols', required=False)
parser.add_argument('--morelevels', dest='moreLevels', action='store_true')

包含指定图像文件输入的选项(唯一必须的参数)
设置垂直比例因子
设置输出文件名
设置 ASCII 输出中的文本列数
添加–morelevels 选项,让用户选择更多层次的灰度梯度

将 ASCII 文本图形字符串写入文本文件

最后,将生成的 ASCII 字符串列表,写入一个文本文件:

# open a new text file
f = open(outFile, 'w')
# write each string in the list to the new file
for row in aimg:
	f.write(row + '\n')
# clean up
f.close()

完整代码

import sys, random, argparse
import numpy as np
import math
from PIL import Image

# 70 levels of gray
gscale1 = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. "

# 10 levels of gray
gscale2 = '@%#*+=-:. '

def getAverageL(image):
    # get the image as a numpy array
    im = np.array(image)
    # get the dimensions
    w,h = im.shape
    # get the average
    return np.average(im.reshape(w*h))

def covertImageToAscii(fileName, cols, scale, moreLevels):
    """
    Given Image and dimensions (rows, cols), returns an m*n list of Images
    """
    # declare globals
    global gscale1, gscale2
    # open image and convert to grayscale
    image = Image.open(fileName).convert('L')
    # store the image dimensions
    W, H = image.size[0], image.size[1]
    print("input image dims: %d x %d" % (W, H))
    # compute tile width
    w = W/cols
    # compute tile height based on the aspect ratio and scale of the font
    h = w/scale
    # compute number of rows to use in the final grid
    rows = int(H/h)
    
    print("cols: %d, rows: %d" % (cols, rows))
    print("tile dims: %d x %d" % (w, h))
    
    # check if image size is too small
    if cols > W or rows > H:
        print("Image too small for specified cols!")
        exit(0)
        
    # an ASCII image is a list of character strings
    aimg = []
    # generate the list of tile dimensions
    for j in range(rows):
        # 计算每个图像小块的起始和结束 y 坐标
        y1 = int(j*h)
        y2 = int((j+1)*h)
        # correct the last tile
        if j == rows-1:
            y2 = H
        # append an empty string
        aimg.append("")
        for i in range(cols):
            # crop the image to fit the tile
            x1 = int(i*w)
            x2 = int((i+1)*w)
            # correct the last tile
            if i == cols-1:
                x2 = W
            # crop the image to extract the tile into another Image object
            img = image.crop((x1, y1, x2, y2))
            # get the average luminance # 获取网格的平均亮度值
            avg = int(getAverageL(img))
            # look up the ASCII character for grayscale value (avg)
            if moreLevels:
                # 将平均亮度值[0,255]对用到70级灰度[0,69]
                gsval = gscale1[int((avg*69)/255)]
            else:
                # 将平均亮度值[0,255]对用到10级灰度[0,9]
                gsval = gscale2[int((avg*9)/255)]
            # append the ASCII character to the string
            aimg[j] += gsval
    # return text image
    return aimg

# main() function
def main():
    # create parser
    descStr = "This program converts an image into ASCII art."
    parser = argparse.ArgumentParser(description=descStr)
    # add expected arguments
    parser.add_argument('--file', dest='imgFile', required=True)
    parser.add_argument('--scale', dest='scale', required=False)
    parser.add_argument('--out', dest='outFile', required=False)
    parser.add_argument('--cols', dest='cols', required=False)
    parser.add_argument('--morelevels', dest='moreLevels', action='store_true')
    
    # parse arguments
    args = parser.parse_args()
    
    imgFile = args.imgFile
    # set output file
    outFile = 'out.txt'
    if args.outFile:
        outFile = args.outFile
    # set scale default as 0.43, which suits a Courier font
    scale = 0.43
    if args.scale:
        scale = float(args.scale)
    # set cols
    cols = 80
    if args.cols:
        cols = int(args.cols)
    print('generating ASCII art...')
    # convert image to ASCII text
    aimg = covertImageToAscii(imgFile, cols, scale, args.moreLevels) 
    
    # open a new text file
    f = open(outFile, 'w')
    # write each string in the list to the new file
    for row in aimg:
        f.write(row + '\n')
    # clean up
    f.close()
    print("ASCII art written to %s" % outFile)
    
# call main
if __name__ == '__main__':
    main()

https://github.com/electronut/pp/blob/master/ascii/ascii.py

将完整代码保存到py文件中

打开终端,切换到ascii.py目录

输入下面代码

$ python ascii.py --file data/robot.jpg --cols 100

将 data/robot.jpg 替换为你想使用的图像文件的相对路径

在这里插入图片描述
使用vscode打开out.txt文件,使用Ctrl±可以缩小,可以看到全屏,只能看10灰度等级

还可使用notepad查看out.txt文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
–morelevels就是70灰度等级

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Git小白入门——了解分布式版本管理和安装

Git是什么&#xff1f; Git是目前世界上最先进的分布式版本控制系统&#xff08;没有之一&#xff09; 什么是版本控制系统&#xff1f; 程序员开发过程中&#xff0c;对于每次开发对各种文件的修改、增加、删除&#xff0c;达到预期阶段的一个快照就叫做一个版本。 如果有一…

EVO大赛是什么

价格是你所付出的东西&#xff0c;而价值是你得到的东西 EVO大赛是什么&#xff1f; “EVO”大赛全称“Evolution Championship Series”&#xff0c;是北美最高规格格斗游戏比赛&#xff0c;大赛正式更名后已经连续举办12年&#xff0c;是全世界最大规模的格斗游戏赛事。常见…

Python Qt学习(四)Radio Button

代码 # -*- coding: utf-8 -*-# Form implementation generated from reading ui file D:\Works\Python\Qt\qt_radiobutton.ui # # Created by: PyQt5 UI code generator 5.15.9 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again.…

2023年高教社杯 国赛数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

(笔记四)利用opencv识别标记视频中的目标

预操作&#xff1a; 通过cv2将视频的某一帧图片转为HSV模式&#xff0c;并通过鼠标获取对应区域目标的HSV值&#xff0c;用于后续的目标识别阈值区间的选取 img cv.imread(r"D:\data\123.png") img cv.cvtColor(img, cv.COLOR_BGR2HSV) plt.figure(1), plt.imshow…

科技助力图书馆新趋势:机器人“图书管理员”展风采

原创 | 文 BFT机器人 PART1 机器人“图书管理员”横空出世 随着科技的日新月异&#xff0c;知识的获取变得更加方便快捷&#xff0c;图书馆不再只是借阅书籍的场所&#xff0c;其渐渐演变成了人们社交、休闲、学习的不二之选。在此场景下&#xff0c;“智能化图书馆”的概念深…

gitbash的使用

目录 1. 安装git 2. gitbash配置 2.1 设置 2.2 生成key 2.3 初始化本地仓库 2.4 clone远程仓库的工程到本地 2.5 本地修改提交 1. 安装git 默认安装。 2. gitbash配置 2.1 设置 打开gitbash&#xff0c;设置用户名和邮箱&#xff1a; git config --global user.name &…

IP协议分片重组问题

分片是什么&&为什么会有分片 IP数据报分片的主要目的是为了防止IP数据报文长度超过下一跳链路MTU(最大传输单元)。 数据链路层之MTU 数据链路层中有一个东西叫做MTU&#xff08;最大传输单元&#xff09;&#xff0c;它的作用主要是控制上层给的数据报不要太大&#…

算法通关村第8关【白银】| 二叉树的深度和高度问题

1.最大深度问题 思路&#xff1a;递归三部曲 第一步&#xff1a;确定参数和返回值 题目要求求二叉树的深度&#xff0c;也就是有多少层&#xff0c;需要传递一个root从底层向上统计 int maxDepth(TreeNode root) 第二步&#xff1a;确定终止条件 当递归到null时就说明到底了…

实训笔记8.28

实训笔记8.28 8.28笔记一、大数据计算场景主要分为两种1.1 离线计算场景1.2 实时计算场景 二、一般情况下大数据项目的开发流程2.1 数据采集存储阶段2.2 数据清洗预处理阶段2.3 数据统计分析阶段2.4 数据挖掘预测阶段2.5 数据迁移阶段2.6 数据可视化阶段 三、纯大数据离线计算项…

最新企业网盘产品推荐榜发布

随着数字化发展&#xff0c;传统的文化存储方式已无法跟上企业发展的步伐。云存储的出现为企业提供了新的文件管理存储模式。企业网盘作为云存储的代表性工具&#xff0c;被越来越多的企业所青睐。那么在众多企业网盘产品中&#xff0c;企业该如何找到合适的企业网盘呢&#xf…

汽车类 ±0.25°C SPI 温度传感器,TMP126EDBVRQ1、TMP126EDCKRQ1、TMP127EDBVRQ1引脚配置图

一、概述 TMP126-Q1 是一款精度为 0.25C 的数字温度传感器 &#xff0c; 支持的环境温度范围为 -55C 至 175C 。TMP126-Q1 具 有 14 位 &#xff08; 有符号 &#xff09; 温度分辨率(0.03125C/LSB)&#xff0c;并且可在 1.62V 至 5.5V 的电源电压范围内工作。TMP126-Q1 具有转…

Python爬虫网络安全:优劣势和适用范围分析

各位Python程序猿大佬们&#xff01;在当今数字化时代&#xff0c;网络安全是至关重要的。保护你的网络通信安全对于个人和组织来说都是非常重要的任务。在本文中&#xff0c;我将与你一起探讨Python网络安全编程中的代理、虚拟专用网络和TLS这三个关键概念&#xff0c;分析它们…

「2024」预备研究生mem-分析推理强化: 分组型 (上)

一、分析推理强化: 分组型 (上) 二、课后题

助力乡村振兴 泰格智能AI英语携手中国善网在行动

近日&#xff0c;泰格智能AI英语与中国善网宣布达成战略合作&#xff0c;共同投身乡村教育事业。此次合作旨在通过中国善网的会员公益机构&#xff0c;向乡村英语老师和学生捐赠共12000个英语教育智能AI训练产品账号&#xff0c;其总价值超过350万人民币。这一举措是为了让乡村…

为何直线导轨要保持日常清洁?

随着时代的发展&#xff0c;已逐步从传统的工业发展模式发展到工业自动化&#xff0c;直线滑轨在工业生产中得到了广泛的应用&#xff0c;大大提高了生产效率&#xff0c;带动了经济效益的增长。 众所周知&#xff0c;想要直线导轨的使用达到预期的效果&#xff0c;日常的保养和…

Vue3 学习

基础 js:https://www.bilibili.com/video/BV15T411j7pJ/?spm_id_from333.337.search-card.all.click&vd_source9747207be61edfe4ec62226fc79b3589 官方文档&#xff1a; https://cn.vuejs.org/ 版本之间差异在关于---》版本发布 https://cn.vuejs.org/about/release…

[Unity]UI和美术出图效果不一致

问题描述&#xff1a;美术使用PS在Gamma空间下设计的UI图&#xff0c;导入到Unity&#xff0c;因为Unity使用的是线性空间&#xff0c;导致半透明的UI效果和美术设计的不一致。 解决方案&#xff1a; &#xff08;一&#xff09;让美术在线性空间下工作 &#xff08;二&…

【C++练习】C++中读取.txt文件中的数据(由简到难)

1 将数据写入.txt文本中&#xff0c;再从.txt中读取到string字符串里&#xff0c;输出到终端 #include <iostream> #include <fstream>//包头文件 using namespace std;int main() {//1. 创建流对象ofstream ofs;//2. 以写的方式打开文件&#xff08;若文件不存在…