python - Windows - 有效地将大量数据打印到终端
问题描述
TL;DR 正在寻找一种方法来加快打印到终端的速度。
我目前正在开发一个项目,该项目基本上可以让您使用 ANSI 转义码在终端中打印出图像,(需要缩小以获得最佳效果,所以我建议使用新的 Windows 终端)
这是代码:
try:
from PIL import Image
except:
from Lib.PIL import Image
from time import time
from os import system
from sys import argv, stdout
from pathlib import Path
def imgToTxt(path: Path, x_ratio: int, y_ratio: int, pixel: str, do_bg: bool, stat: bool, do_prnt: bool, do_warp: bool):
# COLOR FUNCTIONS
fg = lambda c: f"\x1b[38;2;{str(c[0])};{str(c[1])};{str(c[2])}m"
bg = lambda c: f"\x1b[48;2;{str(c[0])};{str(c[1])};{str(c[2])}m"
# /COLOR FUNCTIONS
st = time()
prnt_pixels = list()
_c = False
# IMAGE DATA
im = Image.open(path)
pixels = im.load()
width, height = im.size
# / IMAGE DATA
if stat:
print(height, y_ratio)
print(width, x_ratio)
system("")
# GENERATION LOOP
for y in range(0, height, y_ratio):
if do_warp:
if _c:
_c = False; continue
else:
_c = True
for x in range(0, width, x_ratio):
pu = pixels[x, y]
pl = pixels[x, y + 1 if y + 1 < height else y]
p = fg(pu) + ((bg(pl) if do_warp else bg(pu)) if do_bg else "") + pixel + "\x1b[0m"
prnt_pixels.append(p)
else:
prnt_pixels.append("\n")
# /GENERATION LOOP
# PRINTING
if do_prnt:
for p in prnt_pixels:
stdout.write(p)
# /PRINTING
nd = time()
print(("time to generate", nd - st) if stat else "")
return prnt_pixels
if __name__ == '__main__':
argv.append("-run")
argv.append("True")
if "help" in argv[1]:
print(
""" Convert an image into text
\r line commands:
\r -path [PATH] -- [PATH] full path to the image
\r -xr [INT] -- [INT] number between 1 and size of image, determines the x ratio (1 being raw)
\r -yr [INT] -- [INT] number between 1 and size of image, determines the y ratio (1 being raw)
\r -pix [STR] -- [STR] string of length 2, determines the pixel to use, default 'OO'
\r -do_bg [BOOL] -- [BOOL] boolean, determines if the background has to be filled, default 'True'
\r -do_prnt [BOOL] -- [BOOL] boolean, determines if the image will be displayed, default 'True'
\r -do_warp [BOOL] -- [BOOL] boolean, determines if to warp the image in return for higher quality, default 'False', WARNING this option will force the change of default pixel
\r -help OR /help -- Display this message""")
else:
# ALL
if len(argv) == 1:
argv = input(r'args \>').split(" ")
# /ALL
# SET TO NEXT VALUE
if "-path" in argv:
_ = argv.index("-path") + 1
path = Path(argv[_])
else:
path = r"C:\\Windows\\Cursors\\aero_unavail_xl.cur"
if "-xr" in argv:
_ = argv.index("-xr") + 1
x_ratio = int(argv[_])
else:
x_ratio = 1
if "-yr" in argv:
_ = argv.index("-yr") + 1
y_ratio = int(argv[_])
else:
y_ratio = 1
if "-pix" in argv:
_ = argv.index("-pix") + 1
pix = argv[_]
else:
pix = "00"
# /SET TO NEXT VALUE
# TRUE | FALSE
if "-do_bg" in argv:
_ = argv.index("-xr") + 1
match argv[_].lower():
case 'true':
do_bg = True
case 'false':
do_bg = False
case _:
raise Exception("-do_bg takes only true/false statements")
else:
do_bg = True
if "-do_warp" in argv:
_ = argv.index("-do_warp") + 1
match argv[_].lower():
case 'true':
do_warp = True
pix = '▀'
case 'false':
do_warp = False
case _:
raise Exception("-do_warp takes only true/false statements")
else:
do_warp = False
if "-do_prnt" in argv:
_ = argv.index("-do_prnt") + 1
match argv[_].lower():
case 'true':
do_prnt = True
case 'false':
do_prnt = False
case _:
raise Exception("-do_prnt takes only true/false statements")
else:
do_prnt = True
if "-stat" in argv:
_ = argv.index("-stat") + 1
match argv[_].lower():
case 'true':
stat = True
case 'false':
stat = False
case _:
raise Exception("-stat takes only true/false statements")
else:
stat = True
if "-run" in argv:
_ = argv.index("-run") + 1
match argv[_].lower():
case 'true':
run = True
case 'false':
run = False
case _:
raise Exception("-run takes only true/false statements")
else:
run = False
# /TRUE | FALSE
if run:
imgToTxt(path=path, x_ratio=x_ratio, y_ratio=y_ratio, pixel=pix, do_bg=do_bg, do_prnt=do_prnt, do_warp=do_warp, stat=stat)
它的基本工作方式是获取图像的每个像素颜色数据并为颜色准备正确的 ANSI 代码;
ESC[38;2;{R};{G};{B}m
然后在后期打印它
我一直在寻找一种方法来加快打印过程 IE,使用stdout
,使用单独的循环来生成数据并打印它,我什至尝试使用多个线程(我知道这听起来有多愚蠢......),使用替代缓冲区,但最后我得到了速度提升的一小部分。
有什么办法,即使是疯狂的,可以显着加快这一进程?
解决方案
推荐阅读
- swift - 在 Swift 中继承 NSLayoutConstraint
- r - 在 Shiny 中,我只想在 UI 加载期间更新选择输入()一次
- java - 未找到名称为“默认”的配置 gradle 同步失败
- apache-zeppelin - 在 Windows 10 或 7 的 Apache Zeppelin 中运行 spark 程序时出错
- html - 具有持久纵横比的响应式 CSS 网格
- angular - 角度RouterLinkActive不匹配子路径
- javascript - 传单地图无法识别我的数组变量来自后面代码中的隐藏字段值
- c# - 如何在 C# 和 ASP.NET MVC 中读取/写入 cookie
- foursquare - 从 Foursquare 搜索 api 获取单独的街道号码和街道名称?
- spring-boot - 迁移到最新的 Spring Boot 和 Spring Cloud 后,身份验证服务器 (/oauth/token) 无法正常工作