简体   繁体   English

使用 PIL 在终端中显示图像(png)

[英]Using PIL to show image (png) in terminal

Environment:环境:

Python 3.7.2 Mac OS 10.14.3 Python 3.7.2 Mac 操作系统 10.14.3

I am try to find a way to show a image (jpg/png) in the terminal application.我试图找到一种在终端应用程序中显示图像(jpg/png)的方法。

And I found a working solution for jpg image here:我在这里找到了 jpg 图像的有效解决方案:

Display Images in Linux Terminal using Python使用 Python 在 Linux 终端中显示图像

With the following code:使用以下代码:

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])

The problem is when I try to use this code for a png file I get the error:问题是当我尝试将此代码用于 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.

It seems like when processing a jpg file the pix is a tuple while with a png file the pix is a int value.似乎在处理 jpg 文件时, pix是一个元组,而对于 png 文件, pix是一个 int 值。

Any advice will be appreciated, thanks :)任何建议将不胜感激,谢谢:)

Your image may be greyscale, or palettised.您的图像可能是灰度的或调色的。 Either way there will only be 1 channel, not 3. So change this line无论哪种方式都只会有 1 个通道,而不是 3 个。所以更改此行

img = Image.open(img_path)

to

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

so you get the 3 channels you expect and it all works nicely.所以你得到了你期望的 3 个频道,而且一切都很好。


I noticed that your resizing code tries to keep the same aspect ratio in the resized image, which is all very laudable, but... the pixels on a Terminal are not actually square!我注意到您的调整大小代码试图在调整后的图像中保持相同的纵横比,这都非常值得称赞,但是……终端上的像素实际上并不是方形的! If you look at the cursor up close, it is around 2x as tall as it is wide, so I changed the line of resizing code to allow for this:如果您近距离观察光标,它的高度大约是宽度的 2 倍,因此我更改了调整大小代码行以允许这样做:

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

Keywords : PIL, Pillow, terminal, console, ANSI, escape sequences, graphics, ASCII art, image, image processing, Python关键词:PIL、枕头、终端、控制台、ANSI、转义序列、图形、ASCII 艺术、图像、图像处理、Python

Simply put the recolored img into seven groups as below,只需将重新着色的 img 分成如下七组,

front     |     back        |   color
------------------------------------------
30        |        40       |    black
31        |        41       |    red
32        |        42       |    green
33        |        43       |    yello
34        |        44       |    blue
35        |        45       |    purple
36        |        46       |    violet
37        |        47       |    white
-------------------------------------------

And the code,还有代码,

from PIL import Image  
import numpy as np  
import sys
import os

image = Image.open(sys.argv[1])   
img = np.array(image)

x=5 #step
y=5 #step
img1=img[0:img.shape[0]:x,0:img.shape[1]:y]
#img1=img1 // 37 #resize

for i in range(img.shape[0]//x):
    str = "echo "
    for j in range(img.shape[1]//y):
        if img1[i, j] == 0:
            str=str+'\x1b[41;31m  '
        elif img1[i,j]==1:
            str=str+'\x1b[42;31m  '
        elif img1[i,j]==2:
            str=str+'\x1b[43;31m  '
        elif img1[i,j]==3:
            str=str+'\x1b[44;31m  '
        elif img1[i,j]==4:
            str=str+'\x1b[45;31m  '
        elif img1[i,j]==5:
            str=str+'\x1b[46;31m  '
        elif img1[i, j] == 6:
            str = str + '\x1b[47;31m ' 
    str = str + '\x1b[0m'
    os.system(str)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM