Python实例题:Python3实现图片转彩色字符

news2025/6/3 21:29:37

目录

Python实例题

题目

代码实现

实现原理

图像预处理:

灰度值计算:

字符映射:

彩色输出:

关键代码解析

1. 字符映射和灰度计算

2. 图像模式输出

3. 命令行参数处理

使用说明

基本用法(终端输出):

保存为图像文件:

调整字符画大小:

自定义字符集:

查看完整帮助:

扩展建议

增强功能:

性能优化:

用户界面:

输出格式:

Python实例题

题目

Python3实现图片转彩色字符

代码实现

import argparse
import os
from PIL import Image, ImageDraw, ImageFont
import sys
import termcolor
import platform

class ImageToColorAscii:
    def __init__(self, width=80, height=40, 
                 charset=" .:-=+*#%@", 
                 bg_color=(0, 0, 0), 
                 fill_color=(255, 255, 255),
                 output_mode="terminal"):
        """初始化图片转彩色字符画转换器
        
        Args:
            width: 输出字符画的宽度
            height: 输出字符画的高度
            charset: 用于绘制的字符集,按从暗到亮的顺序排列
            bg_color: 背景颜色,默认为黑色
            fill_color: 填充颜色,默认为白色
            output_mode: 输出模式,可选"terminal"或"image"
        """
        self.width = width
        self.height = height
        self.charset = charset
        self.bg_color = bg_color
        self.fill_color = fill_color
        self.output_mode = output_mode
        self.terminal_support_color = self._check_terminal_color_support()
    
    def _check_terminal_color_support(self):
        """检查终端是否支持彩色输出"""
        if platform.system() == 'Windows':
            return False  # Windows终端默认不支持ANSI颜色
        return True
    
    def convert(self, image_path, output_path=None):
        """将图片转换为彩色字符画
        
        Args:
            image_path: 输入图片路径
            output_path: 输出文件路径,默认为None(直接打印到终端)
        
        Returns:
            转换后的字符画字符串或生成的图片路径
        """
        try:
            # 打开并调整图片大小
            with Image.open(image_path) as img:
                img = img.resize((self.width, self.height), Image.LANCZOS)
                
                # 转换为RGB模式
                img = img.convert("RGB")
                
                # 生成字符画
                if self.output_mode == "terminal":
                    return self._convert_to_terminal(img)
                else:
                    return self._convert_to_image(img, output_path)
        except Exception as e:
            print(f"转换失败: {e}")
            return None
    
    def _convert_to_terminal(self, img):
        """将图片转换为终端彩色字符画
        
        Args:
            img: PIL Image对象
        
        Returns:
            彩色字符画字符串
        """
        ascii_art = []
        
        for y in range(self.height):
            line = []
            for x in range(self.width):
                r, g, b = img.getpixel((x, y))
                
                # 计算灰度值
                gray = int(0.299 * r + 0.587 * g + 0.114 * b)
                
                # 根据灰度值选择字符
                char_index = min(int(gray * len(self.charset) / 256), len(self.charset) - 1)
                char = self.charset[char_index]
                
                # 添加彩色字符
                if self.terminal_support_color:
                    colored_char = termcolor.colored(char, color=None, on_color=None, attrs=None)
                    line.append(colored_char)
                else:
                    line.append(char)
            
            ascii_art.append(''.join(line))
        
        return '\n'.join(ascii_art)
    
    def _convert_to_image(self, img, output_path=None):
        """将图片转换为图像格式的彩色字符画
        
        Args:
            img: PIL Image对象
            output_path: 输出图片路径
        
        Returns:
            输出图片路径
        """
        # 创建新图像
        char_width = 10
        char_height = 18
        output_img = Image.new('RGB', (self.width * char_width, self.height * char_height), self.bg_color)
        draw = ImageDraw.Draw(output_img)
        
        # 尝试加载中文字体
        try:
            font = ImageFont.truetype("simhei.ttf", 14)
        except IOError:
            # 使用默认字体
            font = ImageFont.load_default()
        
        for y in range(self.height):
            for x in range(self.width):
                r, g, b = img.getpixel((x, y))
                
                # 计算灰度值
                gray = int(0.299 * r + 0.587 * g + 0.114 * b)
                
                # 根据灰度值选择字符
                char_index = min(int(gray * len(self.charset) / 256), len(self.charset) - 1)
                char = self.charset[char_index]
                
                # 绘制字符
                draw.text((x * char_width, y * char_height), char, font=font, fill=(r, g, b))
        
        # 保存图像
        if not output_path:
            base, ext = os.path.splitext(os.path.basename(image_path))
            output_path = f"{base}_ascii.png"
        
        output_img.save(output_path)
        return output_path


def main():
    parser = argparse.ArgumentParser(description='图片转彩色字符画工具')
    parser.add_argument('-i', '--input', required=True, help='输入图片路径')
    parser.add_argument('-o', '--output', help='输出文件路径,默认为终端或原文件名加_ascii后缀')
    parser.add_argument('--width', type=int, default=80, help='输出宽度,默认为80')
    parser.add_argument('--height', type=int, default=40, help='输出高度,默认为40')
    parser.add_argument('--charset', default=" .:-=+*#%@", help='字符集,按从暗到亮的顺序排列')
    parser.add_argument('--bg-color', default="0,0,0", help='背景颜色,RGB值,用逗号分隔')
    parser.add_argument('--fill-color', default="255,255,255", help='填充颜色,RGB值,用逗号分隔')
    parser.add_argument('--mode', choices=['terminal', 'image'], default='terminal', help='输出模式,可选terminal或image')
    
    args = parser.parse_args()
    
    # 解析颜色参数
    bg_color = tuple(map(int, args.bg_color.split(',')))
    fill_color = tuple(map(int, args.fill_color.split(',')))
    
    # 创建转换器
    converter = ImageToColorAscii(
        width=args.width,
        height=args.height,
        charset=args.charset,
        bg_color=bg_color,
        fill_color=fill_color,
        output_mode=args.mode
    )
    
    # 执行转换
    result = converter.convert(args.input, args.output)
    
    if result:
        if args.mode == 'terminal':
            print(result)
            print(f"\n字符画宽度: {args.width}, 高度: {args.height}")
        else:
            print(f"彩色字符画已保存到: {result}")
    else:
        print("转换失败")


if __name__ == "__main__":
    main()    

实现原理

这个图片转彩色字符画工具基于以下核心技术实现:

  • 图像预处理

    • 调整图片大小以适应字符画输出
    • 转换为 RGB 模式以便获取每个像素的颜色值
  • 灰度值计算

    • 使用加权平均法计算 RGB 像素的灰度值
    • 公式:gray = 0.299*R + 0.587*G + 0.114*B
  • 字符映射

    • 根据灰度值选择合适的字符
    • 使用从暗到亮的字符集进行映射
  • 彩色输出

    • 终端模式:使用 ANSI 转义序列输出彩色字符
    • 图像模式:创建新图像并在每个位置绘制对应字符

关键代码解析

1. 字符映射和灰度计算

def _convert_to_terminal(self, img):
    ascii_art = []
    
    for y in range(self.height):
        line = []
        for x in range(self.width):
            r, g, b = img.getpixel((x, y))
            
            # 计算灰度值
            gray = int(0.299 * r + 0.587 * g + 0.114 * b)
            
            # 根据灰度值选择字符
            char_index = min(int(gray * len(self.charset) / 256), len(self.charset) - 1)
            char = self.charset[char_index]
            
            # 添加彩色字符
            if self.terminal_support_color:
                colored_char = termcolor.colored(char, color=None, on_color=None, attrs=None)
                line.append(colored_char)
            else:
                line.append(char)
        
        ascii_art.append(''.join(line))
    
    return '\n'.join(ascii_art)

2. 图像模式输出

def _convert_to_image(self, img, output_path=None):
    char_width = 10
    char_height = 18
    output_img = Image.new('RGB', (self.width * char_width, self.height * char_height), self.bg_color)
    draw = ImageDraw.Draw(output_img)
    
    # 尝试加载中文字体
    try:
        font = ImageFont.truetype("simhei.ttf", 14)
    except IOError:
        font = ImageFont.load_default()
    
    for y in range(self.height):
        for x in range(self.width):
            r, g, b = img.getpixel((x, y))
            gray = int(0.299 * r + 0.587 * g + 0.114 * b)
            char_index = min(int(gray * len(self.charset) / 256), len(self.charset) - 1)
            char = self.charset[char_index]
            
            # 绘制字符,使用原始RGB颜色
            draw.text((x * char_width, y * char_height), char, font=font, fill=(r, g, b))
    
    # 保存图像
    if not output_path:
        base, ext = os.path.splitext(os.path.basename(image_path))
        output_path = f"{base}_ascii.png"
    
    output_img.save(output_path)
    return output_path

3. 命令行参数处理

def main():
    parser = argparse.ArgumentParser(description='图片转彩色字符画工具')
    parser.add_argument('-i', '--input', required=True, help='输入图片路径')
    parser.add_argument('-o', '--output', help='输出文件路径')
    parser.add_argument('--width', type=int, default=80, help='输出宽度')
    parser.add_argument('--height', type=int, default=40, help='输出高度')
    parser.add_argument('--charset', default=" .:-=+*#%@", help='字符集')
    parser.add_argument('--bg-color', default="0,0,0", help='背景颜色')
    parser.add_argument('--fill-color', default="255,255,255", help='填充颜色')
    parser.add_argument('--mode', choices=['terminal', 'image'], default='terminal', help='输出模式')
    
    args = parser.parse_args()
    
    # 解析颜色参数
    bg_color = tuple(map(int, args.bg_color.split(',')))
    fill_color = tuple(map(int, args.fill_color.split(',')))
    
    # 创建转换器并执行转换
    converter = ImageToColorAscii(
        width=args.width,
        height=args.height,
        charset=args.charset,
        bg_color=bg_color,
        fill_color=fill_color,
        output_mode=args.mode
    )
    
    result = converter.convert(args.input, args.output)
    
    if result:
        if args.mode == 'terminal':
            print(result)
        else:
            print(f"彩色字符画已保存到: {result}")

使用说明

  • 基本用法(终端输出)

python image_to_color_ascii.py -i input.jpg
  • 保存为图像文件

python image_to_color_ascii.py -i input.jpg -o output.png --mode image
  • 调整字符画大小

python image_to_color_ascii.py -i input.jpg --width 120 --height 60
  • 自定义字符集

python image_to_color_ascii.py -i input.jpg --charset " .:;+=xX$#@"
  • 查看完整帮助

python image_to_color_ascii.py --help

扩展建议

  • 增强功能

    • 添加对动图的支持
    • 实现不同的字符渲染算法
    • 添加艺术滤镜效果
    • 支持视频转字符动画
  • 性能优化

    • 使用 NumPy 加速图像处理
    • 优化字符选择算法
    • 实现多线程处理
  • 用户界面

    • 开发图形界面版本
    • 添加实时预览功能
    • 支持交互式调整参数
  • 输出格式

    • 支持导出为 HTML、SVG 等格式
    • 添加对不同字体的支持
    • 实现彩色 PDF 输出

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2395494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于物联网(IoT)的电动汽车(EVs)智能诊断

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从&#x…

JDBC+HTML+AJAX实现登陆和单表的CRUD

JDBCHTMLAJAX实现登陆和单表的CRUD 导入maven依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocatio…

【C++】位图详解(一文彻底搞懂位图的使用方法与底层原理)

&#x1f308; 个人主页&#xff1a;谁在夜里看海. &#x1f525; 个人专栏&#xff1a;《C系列》《Linux系列》 ⛰️ 天高地阔&#xff0c;欲往观之。 目录 1.位图的概念 2.位图的使用方法 定义与创建 设置和清除 位访问和检查 转换为其他格式 3.位图的使用场景 1.快速…

【笔记】开源通用人工智能代理 Suna 部署全流程准备清单(Windows 系统)

#工作记录 一、基础工具与环境 开发工具 Git 或 GitHub Desktop&#xff08;代码管理&#xff09;Docker Desktop&#xff08;需启用 WSL2&#xff0c;容器化部署&#xff09;Python 3.11&#xff08;推荐版本&#xff0c;需添加到系统环境变量&#xff09;Node.js LTS&#xf…

海康工业相机SDK二次开发(VS+QT+海康SDK+C++)

前言 工业相机在现代制造和工业自动化中扮演了至关重要的角色&#xff0c;尤其是在高精度、高速度检测中。海康威视工业相机以其性能稳定、图像质量高、兼容性强而受到广泛青睐。特别是搞机器视觉的小伙伴们跟海康打交道肯定不在少数&#xff0c;笔者在平常项目中跟海康相关人…

深度学习|pytorch基本运算-乘除法和幂运算

【1】引言 前序学习进程中&#xff0c;已经对pytorch张量数据的生成和广播做了详细探究&#xff0c;文章链接为&#xff1a; 深度学习|pytorch基本运算-CSDN博客 深度学习|pytorch基本运算-广播失效-CSDN博客 上述探索的内容还止步于张量的加减法&#xff0c;在此基础上&am…

4.2.4 Spark SQL 数据写入模式

在本节实战中&#xff0c;我们详细探讨了Spark SQL中数据写入的四种模式&#xff1a;ErrorIfExists、Append、Overwrite和Ignore。通过具体案例&#xff0c;我们演示了如何使用mode()方法结合SaveMode枚举类来控制数据写入行为。我们首先读取了一个JSON文件生成DataFrame&#…

论文笔记: Urban Region Embedding via Multi-View Contrastive Prediction

AAAI 2024 1 INTRO 之前基于多视图的region embedding工作大多遵循相同的模式 单独的单视图表示多视图融合 但这种方法存在明显的局限性&#xff1a;忽略了不同视图之间的信息一致性 一个区域的多个视图所携带的信息是高度相关的&#xff0c;因此它们的表示应该是一致的如果能…

初学者如何微调大模型?从0到1详解

本文将手把手带你从0到1&#xff0c;详细解析初学者如何微调大模型&#xff0c;让你也能驾驭这些强大的AI工具。 1. 什么是大模型微调&#xff1f; 想象一下&#xff0c;预训练大模型就像一位博览群书但缺乏专业知识的通才。它掌握了海量的通用知识&#xff0c;但可能无法完美…

西瓜书第十一章——降维与度量学习

文章目录 降维与度量学习k近邻学习原理头歌实战-numpy实现KNNsklearn实现KNN 降维——多维缩放&#xff08;Multidimensional Scaling, MDS&#xff0c;MDS&#xff09;提出背景与原理重述1.**提出背景**2.**数学建模与原理推导**3.**关键推导步骤** Principal Component Analy…

Portainer安装指南:多节点监控的docker管理面板-家庭云计算专家

背景 Portainer 是一个轻量级且功能强大的容器管理面板&#xff0c;专为 Docker 和 Kubernetes 环境设计。它通过直观的 Web 界面简化了容器的部署、管理和监控&#xff0c;即使是非技术用户也能轻松上手。Portainer 支持多节点管理&#xff0c;允许用户从一个中央控制台管理多…

vscode实用配置

前端开发安装插件&#xff1a; 1.可以更好看的显示文件图标 2.用户快速打开文件 使用步骤&#xff1a;在html文件下右键点击 open with live server 即可 刷力扣&#xff1a; 安装这个插件 还需要安装node.js即可

React 项目中封装 Excel 导入导出组件:技术分享与实践

文章目录 前言一、为什么需要封装 Excel 组件&#xff1f;二、技术选型三、核心实现1. 安装依赖2. 封装Excel导出3. 封装导入组件 &#xff08;UploadExcel&#xff09; 总结 前言 在 React 项目中&#xff0c;处理 Excel 文件的导入和导出是常见的业务需求。无论是导出报表数…

【2025CCF中国开源大会】RISC-V 开源生态的挑战与机遇分论坛重磅来袭!共探开源芯片未来

点击蓝字 关注我们 CCF Opensource Development Committee 开源浪潮正从软件席卷硬件领域&#xff0c;RISC-V作为全球瞩目的开源芯片架构&#xff0c;正在重塑计算生态的版图&#xff01;相较于成熟的x86与ARM&#xff0c;RISC-V生态虽处爆发初期&#xff0c;却蕴藏着无限可能。…

python完成批量复制Excel文件并根据另一个Excel文件中的名称重命名

import openpyxl import shutil import os # 原始文件路径 original_file "C:/Users/Administrator/Desktop/事业联考面试名单/郑州.xlsx" # 读取包含名称的Excel文件 # 修改为您的文件名 wb openpyxl.load_workbook( "C:/Users/Administrator/Desktop/事…

Vue-2-前端框架Vue基础入门之二

文章目录 1 计算属性1.1 计算属性简介1.2 计算属性示例 2 侦听器2.1 简单的侦听器2.2 深度监听2.3 监听对象单个属性 3 vue-cli3.1 工程化的Vue项目3.2 Vue项目的运行流程 4 vue组件4.1 Vue组件的三个部分4.1.1 template4.1.2 script4.1.3 style 4.2 组件之间的关系4.2.1 使用组…

CPT208 Human-Centric Computing 人机交互 Pt.7 交互和交互界面

文章目录 1. 界面隐喻&#xff08;Interface metaphors&#xff09;1.1 界面隐喻的应用方式1.2 界面隐喻的优缺点 2. 交互类型2.1 Instructing&#xff08;指令式交互&#xff09;2.2 Conversing&#xff08;对话式交互&#xff09;2.3 Manipulating&#xff08;操作式交互&…

[网页五子棋][匹配模块]前后端交互接口(消息推送机制)、客户端开发(匹配页面、匹配功能)

让多个用户&#xff0c;在游戏大厅中能够进行匹配&#xff0c;系统会把实力相近的两个玩家凑成一桌&#xff0c;进行对战 约定前后端交互接口 消息推送机制 匹配这样的功能&#xff0c;也是依赖消息推送机制的 玩家 1 点击开始匹配按钮&#xff0c;就会告诉服务器&#xff1…

【数据分析】Matplotlib+Pandas+Seaborn绘图

【数据分析】MatplotlibPandasSeaborn绘图 &#xff08;一&#xff09;Matplotlib绘图1.1 matplotlib绘图方式1: 状态接口1.2 matplotlib绘图方式2: 面向对象1.3 通过安斯科姆数据集, 说明可视化的重要性1.4 MatPlotlib绘图-单变量-直方图1.5 MatPlotlib绘图-双变量-散点图1.6 …

NLP学习路线图(十五):TF-IDF(词频-逆文档频率)

在自然语言处理&#xff08;NLP&#xff09;的浩瀚宇宙中&#xff0c;TF-IDF&#xff08;词频-逆文档频率&#xff09; 犹如一颗恒星&#xff0c;虽古老却依然璀璨。当ChatGPT、BERT等大模型光芒四射时&#xff0c;TF-IDF作为传统方法的代表&#xff0c;其简洁性、高效性与可解…