Использование PIL для показа изображения (png) в терминале - PullRequest
0 голосов
/ 20 февраля 2019

Среда:

Python 3.7.2 Mac OS 10.14.3

Я пытаюсь найти способ показать изображение (jpg / png) в терминальном приложении.

И я нашел рабочее решение для изображения jpg здесь:

Отображение изображений в терминале Linux с использованием Python

со следующим кодом:

import numpy as np
from PIL import Image

def get_ansi_color_code(r, g, b):
    if r == g and g == b:
        if r < 8:
            return 16
        if r > 248:
            return 231
        return round(((r - 8) / 247) * 24) + 232
    return 16 + (36 * round(r / 255 * 5)) + (6 * round(g / 255 * 5)) + round(b / 255 * 5)

def get_color(r, g, b):
    return "\x1b[48;5;{}m \x1b[0m".format(int(get_ansi_color_code(r,g,b)))

def show_image(img_path):
    try:
        img = Image.open(img_path)
    except FileNotFoundError:
        exit('Image not found.')
    h = 100
    w = int((img.width / img.height) * h)
    img = img.resize((w, h), Image.ANTIALIAS)
    img_arr = np.asarray(img)

    for x in range(0, h):
        for y in range(0, w):
            pix = img_arr[x][y]
            print(get_color(pix[0], pix[1], pix[2]), sep='', end='')
        print()

if __name__ == '__main__':
    show_image(sys.argv[1])

Проблема в том, что когда я пытаюсь использовать этот код для файла png, я получаю сообщение об ошибке:

Traceback (most recent call last):
  File "img-viewer.py", line 62, in <module>
    show_image(sys.argv[1])
  File "img-viewer.py", line 40, in show_image
    print(get_color(pix[0], pix[1], pix[2]), sep='', end='')
IndexError: invalid index to scalar variable.

Кажется, что при обработке файла jpg pix - это кортеж, а с pngфайл pix является значением типа int.

Любой совет будет оценен, спасибо:)

1 Ответ

0 голосов
/ 20 февраля 2019

Ваше изображение может быть в оттенках серого или в палитре.В любом случае будет только 1 канал, а не 3. Поэтому измените эту строку

img = Image.open(img_path)

на

img = Image.open(img_path).convert('RGB')

, чтобы вы получили 3 ожидаемых канала, и все это прекрасно работает.


Я заметил, что ваш код изменения размера пытается сохранить такое же соотношение сторон в измененном изображении, что очень похвально, но ... пиксели на терминале на самом деле не квадратные!Если вы посмотрите на курсор близко, он примерно в 2 раза больше его высоты, поэтому я изменил строку кода изменения размера, чтобы учесть это:

w = int((img.width / img.height) * h) * 2

Ключевые слова :PIL, Подушка, терминал, консоль, ANSI, escape-последовательности, графика, ASCII art, изображение, обработка изображений, Python

...