python - 有没有办法优化这个字典搜索?
问题描述
我有一些代码可以打开图像并使用 ANSI 转义序列将图像的表示打印到终端。它获取图像缩小版本中的每个像素,并使用与其匹配的颜色打印一个字符。然而,并非所有终端都支持 RGB 输出,所以我想实现其他颜色模式,例如 4 位。我使用包含 ANSI 代码和它们产生的 RGB 值的字典查找表来做到这一点:{(r, g, b) : code, ...
. 然后我根据欧几里德距离打印最接近像素颜色的值。
from PIL import Image, ImageOps
from math import sqrt, inf
def match_colour_to_table(table, colour):
best_colour = None
best_diff = inf
for table_colour in table.keys():
# Calculate the distance between the two colours
delta = (c - t for c, t in zip(colour, table_colour))
diff = sqrt(sum((p ** 2 for p in delta)))
if diff < best_diff:
best_colour = table_colour
best_diff = diff
return table[selected_colour]
def term_pixel_4bit(colour):
colour_table = {
(0, 0, 0) : 40,
(255, 0, 0) : 41,
(0, 255, 0) : 42,
(255, 255, 0) : 43,
(0, 0, 255) : 44,
(255, 0, 255) : 45,
(0, 255, 255) : 46,
(255, 255, 255) : 47,
}
code = match_colour_to_table(colour_table, colour)
return f"\033[;{code}m \033[0m"
def term_pixel_256(colour):
match_colour_to_table(TABLE_256, colour)
return f"\033[48;5;{code}m ";
def print_image(image, size):
width, height = size
image = image.resize(size, resample=1).convert("RGB")
# Print each row of characters
for y in range(height):
row = [term_pixel_256(image.getpixel((x, y)))
for x in range(width)]
# Reset to avoid trailing colours
row.append("\033[0m")
printf("".join(row))
这种方法对于 4 位颜色效果很好,但对于 256 色效果则差很多。我将https://jonasjacek.github.io/colors/data.json上的 json 数据转换为字典。
TABLE_256 = {
(0, 0, 0) : 0, (128, 0, 0) : 1, (0, 128, 0) : 2,
...
(228, 228, 228) : 254, (238, 238, 238) : 255
}
它确实产生了一个漂亮的结果,但可以理解的是它需要一段时间来计算。我确信有一种更快的方法可以做到这一点,但我不完全确定从哪里开始。任何帮助将非常感激。
以防万一,这里是调用站点:
path = os.path.join(os.path.dirname(__file__), "")
image = Image.open(path + sys.argv[1])
print_image(image, (100, 50))
解决方案
您可以尝试将functools.lru_cache应用于term_pixel_4bit
import functools
@functools.lru_cache
def term_pixel_256(colour):
match_colour_to_table(TABLE_256, colour)
return f"\033[48;5;{code}m ";
推荐阅读
- javascript - 使用数组将动态添加的 li 和 ul 元素保存到数据库
- python - 使用多处理写入多个文件。错误:“TypeError:无法序列化 '_io.TextIOWrapper' 对象”
- docker - 如何设置 docker date 并确保它不与我的系统时间同步?
- python - How to construct regex to identify dollar ($) money sum
- r - 与 R 的网络定制作斗争
- javascript - ag-grid 复制并粘贴带有双引号的单元格
- bash - 访问 SGE 作业脚本标题中设置的变量
- angular - 必须在索引处为表单控件提供一个值:1 - 错误
- java - Intellij IDEA 2018.2 无法识别带有 JDK 10 的 JavaFX 包
- python - OpenCV中Trackbar的负值范围