python纯终端实现图片查看器(全彩)(windows)
很多人作为命令行爱好者,无法在终端内直接查看图片是无法忍受的,
那就写一个!

先直接上代码
import os
import sys
from PIL import Image
import numpy as np
import colorama
import msvcrt # Windows专用# 初始化colorama
colorama.init()# 更丰富的字符梯度,用于更好的放大效果chars = [" ", "░", "▒", "▓", "█", "▀", "▄", "▌", "▐", "■", "◢", "◣", "◤", "◥", "◧", "◨", "◩", "◪", "◫"]def clear_screen():"""清屏"""os.system('cls' if os.name == 'nt' else 'clear')def image_to_ansiart(image_path, width=80, scale=1.0):"""将图片转换为ANSI彩色字符画,支持平滑缩放"""try:img = Image.open(image_path)except Exception as e:return f"[无法加载图片: {str(e)}]"# 应用缩放因子width = int(width * scale)aspect_ratio = img.height / img.widthheight = int(width * aspect_ratio * 0.45) # 调整高宽比以获得更好显示效果# 确保最小尺寸width = max(10, width) # 最小宽度设为10height = max(5, height) # 最小高度设为5# 使用高质量缩放img = img.resize((width, height), Image.Resampling.LANCZOS)img = img.convert("RGB")pixels = np.array(img)ansi_lines = []for row in pixels:line = []for pixel in row:r, g, b = pixelbrightness = 0.299 * r + 0.587 * g + 0.114 * b# 选择字符,使用更精细的亮度分级char_idx = int(brightness / 255 * (len(chars) - 1))char = chars[char_idx]# 使用24位真彩色line.append(f"\x1b[38;2;{r};{g};{b}m{char}")ansi_lines.append("".join(line) + "\x1b[0m")return "\n".join(ansi_lines)def get_terminal_size():"""获取终端大小"""try:from shutil import get_terminal_size as gtsreturn gts().columns, gts().linesexcept:return 80, 24 # 默认值def get_image_list(start_image=None):"""获取当前目录图片列表,并定位到指定图片"""images = sorted([f for f in os.listdir() if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.webp'))])if not images:print("当前目录没有图片文件(支持.png/.jpg/.jpeg/.bmp/.gif/.webp)")return None, -1# 如果指定了初始图片,尝试定位idx = 0if start_image:start_image = os.path.basename(start_image) # 只取文件名部分try:idx = images.index(start_image)except ValueError:# 如果文件不在当前目录,添加到列表并设为当前图片if os.path.exists(start_image):images.append(start_image)images.sort()idx = images.index(start_image)else:print(f"警告: 指定的图片文件 {start_image} 不存在")return images, idxdef main():# 处理命令行参数start_image = sys.argv[1] if len(sys.argv) > 1 else None# 获取图片列表和初始索引images, idx = get_image_list(start_image)if not images:returnscale = 1.0base_width = min(80, get_terminal_size()[0] - 10) # 根据终端宽度调整while True:clear_screen()# 显示图片信息和控制说明print(f"图片查看器: {images[idx]} ({idx+1}/{len(images)}) 缩放: {scale:.1f}x")print("← →:切换图片 | + -:缩放(0.2x-5.0x) | Home/End:首图/末图 | Q:退出")print("-" * min(80, get_terminal_size()[0]))try:# 显示图片art = image_to_ansiart(images[idx], base_width, scale)print(art)except Exception as e:print(f"渲染错误: {str(e)}")# 获取按键key = msvcrt.getch()try:key = key.decode('utf-8').lower()except:key = str(key)# 处理按键if key == 'q':breakelif key == '+' and scale < 5.0:scale = min(5.0, scale + 0.1) # 更精细的缩放控制elif key == '-' and scale > 0.2:scale = max(0.2, scale - 0.1)elif key == '\x00' or key == '\xe0': # 功能键前缀next_key = msvcrt.getch()if next_key == b'M' or next_key == b'P': # 右箭头或下箭头idx = (idx + 1) % len(images)scale = 1.0elif next_key == b'K' or next_key == b'H': # 左箭头或上箭头idx = (idx - 1) % len(images)scale = 1.0elif next_key == b'G': # Home键idx = 0scale = 1.0elif next_key == b'O': # End键idx = len(images) - 1scale = 1.0elif key == '\r': # 回车键重置缩放scale = 1.0elif key == 'f': # 切换全屏/正常模式base_width = get_terminal_size()[0] - 10 if base_width < 100 else 80if __name__ == "__main__":try:main()except KeyboardInterrupt:passexcept Exception as e:print(f"程序出错: {str(e)}")finally:# 重置终端print("\x1b[0m") # 重置所有属性colorama.deinit()
运行:
python viewer.py myphoto.jpg
直接
python viewer.py
也可以
效果图:

-和+可以放大缩小
(提示:windows终端 ctrl + 放大字体,ctrl - 缩小字体,缩小字体效果更佳)
相关文章:
python纯终端实现图片查看器(全彩)(windows)
很多人作为命令行爱好者,无法在终端内直接查看图片是无法忍受的, 那就写一个! 先直接上代码 import os import sys from PIL import Image import numpy as np import colorama import msvcrt # Windows专用# 初始化colorama colorama.ini…...
【动态规划篇】- 路径问题
62. 不同路径 题目链接: 62. 不同路径 题目解析: 状态表示 dp[i][j]表示:以[i][j]为终点时,一共有多少种路径。 状态转移方程 以[i][j]最近的几步来分析问题,要么从[i-1][j]位置向下走一步到达[i][j],要么从[i][j-1…...
《新凯来:半导体设备制造领域的“国家队”》
《新凯来:半导体设备制造领域的“国家队”》 一、SEMICON China 爆火出圈:31 款设备背后的 “深圳力量” 1.1 展会现象级热度 在 2025 年 SEMICON China 展会现场,新凯来展台成了整届展会当之无愧的 “顶流”,被来自全球各地的专…...
AI大模型最新发布[update@202503]
OpenAI GPT-4o:多模态,“o”代表Omni,即全能的意思,凸显了其多功能的特性。 多模态交互,GPT-4o可以接受文本、音频和图像的任意组合作为输入,并生成文本、音频和图像的任意组合输出。实时推理能力&#x…...
深入浅出 Embedding
1. 什么是 Embedding? Embedding(嵌入)是一种将高维数据映射到低维连续空间的技术,用于表达数据的语义关系。简单来说,它是一种向量化表示,将文本、图像、用户行为等信息转换为数值向量,使得相似的数据在向量空间中距离更近。 2. 如何理解 Embedding? 2.1 浅显易懂的…...
java项目之基于ssm的乡镇自来水收费系统(源码+文档)
项目简介 乡镇自来水收费系统实现了以下功能: 乡镇自来水收费系统在Eclipse环境中,使用Java语言进行编码,使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务,其管理员管理水表,审核用户更换…...
Java实战:实现用户的登录注册功能
系列文章目录 Java文件 I/O流的操作实战和高级UI组件和事件监听的综合 文章目录 系列文章目录前言一、大致流程思路分析:二、定义用户类:三、服务层的实现: 1.保护用户数据功能的实现2.登录操作的实现 四、实现用户的注册界面: 大…...
Spring AI MCP 架构详解
Spring AI MCP 架构详解 1.什么是MCP? MCP 是一种开放协议,它对应用程序向大语言模型(LLMs)提供上下文信息的方式进行了标准化。可以把 MCP 想象成人工智能应用程序的 USB-C 接口。就像 USB-C 为将设备连接到各种外围设备和配件提供了一种…...
目标识别与双目测距(1)环境搭建:Ubuntu+yolov5+pcl库
环境情况 ubuntu 18.04 → 20.04(最终) 安装Ubuntu1804虚拟机系统 Anaconda:可参考我的另一篇文章 Python 3.6.13 → 3.8(最终)Anaconda3-2021.05 目标识别:YOLOv5相关 1、安装git sudo apt install gi…...
OpenAI API - Agent
文章目录 代理概述模型工具知识与记忆防护栏编排入门 语音代理选择正确的架构语音到语音(多模态)架构链式架构 构建语音代理使用语音到语音架构进行实时处理将音频输入链接到文本处理 → 音频输出 代理 了解如何使用 OpenAI API 构建代理。 https://pl…...
excel 时间戳 转日期
在Excel中,将时间戳转换为日期格式,可以使用以下步骤和方法: 一、了解时间戳 时间戳(Timestamp)通常是从1970年1月1日(UTC时间)开始的秒数或毫秒数。这个时间点被称为“Unix纪元”或“Unix时间…...
Strawberry perl的下载,查询版本号,配置Path环境变量,查找perl解释器的位置
Strawberry Perl 是一个适用于 Microsoft Windows 的 Perl 环境,包含运行和开发 Perl 应用程序所需的一切。它旨在尽可能接近 UNIX 系统上的 Perl 环境。 下载 官网: Strawberry Perl for Windows - Releases 各个版本: Strawberry Perl for Windows - Releases …...
MySQL的基础语法2(函数-字符串函数、数值函数、日期函数和流程函数 )
目录 一、字符串函数 1.常见字符串函数 编辑 2.字符串函数的基本使用 3.字符串函数的数据库案例演示 二、数值函数 1.常见数值函数(如下): 2.数值函数的基本使用 3.数值函数的数据库案例演示 三、日期函数 1.常见的日期函数 2.日…...
5G_WiFi_CE_杂散测试
目录 一、规范要求 1、法规目录: 2、限值: (1)带外发射杂散 (2)带内发射杂散 (3)接收杂散 二、测试方法 1、带外发射杂散 (1)测试条件 (…...
理解Kubernetes中CoreDNS域名解析与DNS策略
CoreDNS是什么 CoreDNS是一个灵活可扩展的DNS服务器,使用Go语言编写,旨在提供快速、灵活的DNS服务 为什么需要CoreDNS CoreDNS为Kubernetes集群内部的DNS解析提供服务,使得服务之间能够通过域名互相通信 Kubernetes集群中, CoreDNS是运行在…...
大数据Spark(五十五):Spark框架及特点
文章目录 Spark框架及特点 一、Spark框架介绍 二、Spark计算框架具备以下特点 Spark框架及特点 一、Spark框架介绍 Apache Spark 是一个专为大规模数据处理而设计的快速、通用的计算引擎。最初由加州大学伯克利分校的 AMP 实验室(Algorithms, Machines, and Pe…...
UI产品经理基础(六):如何解决用户的质疑?
在需求调查中遇到用户质疑“不专业”或“不了解需求”,本质上是用户对产品经理的信任缺失或沟通鸿沟导致的。要化解这种质疑,需从专业能力展示、沟通方式优化、用户参与感提升三个维度切入,结合具体场景采取针对性策略。以下是系统化的解决方…...
【大数据技术】大数据技术概念及概述
1. 大数据概念 数据 是实时或观察的结果是对客观事务的逻辑归纳是用于表示客观事物的未经加工的原始素材 数据的产生 对客观事务的计量和记录尝试的数据 单位换算1 byte8 bit1 k1024 byte1 mb1024 k1 g1024 m1 t1024 g1 p1024 t1 e1024 p1 z1024 e1 y1024 z1 b1024 y1 n10…...
高等数学-第七版-上册 选做记录 习题7-4
1. 2....
Python库()
1.概念 Matplotlib 库:是一款用于数据可视化的 Python 软件包,支持跨平台运行,它能够根据 NumPy ndarray 数组来绘制 2D 图像,它使用简单、代码清晰易懂 Matplotlib 图形组成: Figure:指整个图形…...
AI知识补全(八):多模态大模型是什么?
名人说:人生如逆旅,我亦是行人。 ——苏轼《临江仙送钱穆父》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:AI知识补全(七):AI Agent 智能…...
复习MySQL20250327
第一章 基本操作 一、管理数据库 难点:创建数据库 输入cmd的MySQL安装路径C:\Program Files\MySQL\MySQL Server 8.0\bin 1.查看所有数据库 show databases; 2.创建数据库 create database hsusers default charset utf8 collate utf8_general_ci;create data…...
Docker-MySQL安装-命令解读-常见命令-数据卷挂载-本地目录挂载-自定义镜像-网络-前端部署-DockerCompose
目录 Docker: 安装MySQL: 镜像容器: 镜像仓库: 编辑命令解读: 镜像命名规范: docker run中常见参数: Docker常见命令: 编辑数据卷: 编辑数据卷-操作命令&…...
Docker 安装部署Harbor 私有仓库
Docker 安装部署Harbor 私有仓库 系统环境:redhat x86_64 一、首先部署docker 环境 定制软件源 wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repoyum install -y yum-utils device-mapper-persistent-data lvm2…...
linux基本命令(1)--linux下的打包命令 -- tar 和gzip
tar 解压 ,打包 语法:tar [主选项辅选项] 文件或者目录 使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用。 主选项: c 创建新的档案文件。如果用户想备…...
Linux 文件系统全解析
笔记整理自 【双语视界】Linux文件系统全解析:从混乱到标准,一览核心目录! 可执行文件目录 /bin(基本系统命令) 包含核心操作系统程序,在系统启动时必须可用,即使没有挂载 /usr 也能运行。 这里…...
StarRocks 存算分离在京东物流的落地实践
康琪:京东物流高级技术专家、StarRocks & Apache Flink Contributor 导读:本文整理自京东物流高级技术专家在 StarRocks 年度峰会上的分享,UData 平台从存算一体到存算分离架构演进后,查询性能得到提升。Cache hit 时…...
英伟达GB300新宠:新型LPDDR5X SOCAMM内存
随着人工智能(AI)、机器学习(ML)和高性能计算(HPC)应用的快速发展,对于高效能、大容量且低延迟内存的需求日益增长。NVIDIA在其GB系列GPU中引入了不同的内存模块设计,以满足这些严格…...
HTML布局
HTML布局元素 <header>定义文档或者节的页眉 <nav>定义导航链接的容器 <section>定义文档中的一部分 <article>定义单独的文章 <aside>定义内容边栏(如侧边栏) footer定义文档或节的页脚 <details>定义额外的细节 …...
vue搭建一个树形菜单项目
首先搭建项目需要先通过步骤搭建一个vue的项目,然后创建一个component文件,里面新建一个index.vue页面来。 这是引入的element-ui组件库里的组件,来实现我的路由,渲染的是我存储的动态路由,所以需要先安装并且引用。 …...
