Python兴趣编程百例:手把手带你开发一个图片转字符图的小工具

在数字世界的无尽探索中,我们时常被那些看似平凡的技术所启发,它们如同星辰般点缀着我们的创意天空。今天,我突发奇想,想要用Python开发一个将图片转化为字符画的小工具。这不仅是一次技术的实践,更是一场艺术与科技的奇妙融合。

让我们一起踏上这段旅程,用Python的代码,绘制出属于我们自己的字符画世界。在这个世界里,每一行代码都是一笔,每一次运行都是一次创作,每一张字符画都是一次心灵的触动。

1.功能概述

使用PyQt5框架开发的ASCII字符画生成器。用户可以通过该程序加载图片,将其转换为ASCII字符表示,并保存生成的ASCII字符画。

效果图 

2.设计思路

  1. 用户界面设计:使用PyQt5创建一个图形用户界面,包括图片显示区域、文本编辑区域、ASCII字符设置区域和操作按钮。
  2. 图片处理:加载图片后,调整图片大小并转换为灰度图像,以便于生成ASCII艺术。
  3. ASCII艺术生成:根据灰度图像的像素值,将每个像素映射到预设的ASCII字符集中的一个字符。
  4. 保存ASCII艺术:将生成的ASCII字符串保存为文本文件。

3.主要函数解析

  • __init__:初始化主窗口,设置UI元素。
  • initUI:设置窗口标题和布局,添加必要的控件和按钮。
  • load_image:打开文件对话框,加载用户选择的图片。
  • resize_image:调整图片大小,保持宽高比。
  • grayify:将图片转换为灰度图像。
  • generate_ascii:生成ASCII艺术,将灰度图像转换为ASCII字符串,并在文本编辑器中显示。
  • save_ascii:保存生成的ASCII艺术到文本文件。
  • pixels_to_ascii:将灰度图像的像素转换为ASCII字符。

4.详细设计

  1. 界面设计

    • 左侧区域用于显示原始图片。
    • 右侧上半部分用于显示生成的ASCII字符。
    • 右侧下半部分包括:
      • 自定义ASCII字符输入框。
      • 加载图片、生成ASCII、保存ASCII的按钮。
  2. 功能实现

    • 加载图片:用户点击按钮后,通过文件对话框选择图片文件,加载并显示在左侧区域。
    • 生成ASCII:点击按钮后,程序将图片转换为灰度并调整大小,然后根据灰度值映射到ASCII字符,结果显示在右侧文本编辑区域。
    • 保存ASCII:用户点击按钮后,选择保存位置和文件名,将文本编辑区域的内容保存为文本文件。
  3. 错误处理

    • 在加载图片和生成ASCII时,程序会检查是否有图片路径,如果没有则不执行后续操作。
    • 在生成ASCII时,如果自定义的ASCII字符集为空,程序会提示用户输入。
  4. 用户体验

    • 提供清晰的界面布局和直观的操作流程。
    • 在执行可能耗时的操作(如生成ASCII)时,提供进度反馈或加载指示。

5.完整代码 

# -*- coding: gbk -*-
"""
Created on 2024/6/18 11:22@Deprecated: 
@Author: DanMo
@File : ASCIIArtGenerator.py
"""
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QTextEdit, QFileDialog, QVBoxLayout, \QHBoxLayout, QWidget, QLineEdit
from PyQt5.QtGui import QPixmap
from PIL import Imageclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.ASCII_CHARS = '@%#*+=-:. 'self.initUI()def initUI(self):self.setWindowTitle('ASCII Art Generator')central_widget = QWidget(self)self.setCentralWidget(central_widget)# 创建布局main_layout = QHBoxLayout(central_widget)# 左侧显示图片的部分self.label = QLabel(self)main_layout.addWidget(self.label)# 右侧操作部分right_layout = QVBoxLayout()self.textEdit = QTextEdit(self)right_layout.addWidget(self.textEdit)# 添加设置ASCII字符的部分ascii_label = QLabel('Custom ASCII Chars:', self)right_layout.addWidget(ascii_label)self.ascii_edit = QLineEdit(self)self.ascii_edit.setText(self.ASCII_CHARS)right_layout.addWidget(self.ascii_edit)button_layout = QHBoxLayout()self.btnLoad = QPushButton('Load Image', self)self.btnLoad.clicked.connect(self.load_image)button_layout.addWidget(self.btnLoad)self.btnGenerate = QPushButton('Generate ASCII', self)self.btnGenerate.clicked.connect(self.generate_ascii)button_layout.addWidget(self.btnGenerate)self.btnSave = QPushButton('Save ASCII', self)self.btnSave.clicked.connect(self.save_ascii)button_layout.addWidget(self.btnSave)right_layout.addLayout(button_layout)main_layout.addLayout(right_layout)self.resize(800, 600)  # 初始窗口大小def load_image(self):options = QFileDialog.Options()fileName, _ = QFileDialog.getOpenFileName(self, "Open Image File", "", "Image Files (*.png *.jpg *.jpeg *.bmp)",options=options)if fileName:pixmap = QPixmap(fileName)self.label.setPixmap(pixmap)self.image_path = fileName# 调整图片尺寸并灰度化def resize_image(self, image, new_width=100):width, height = image.sizeratio = height / width / 2new_height = int(new_width * ratio)resized_image = image.resize((new_width, new_height))return resized_imagedef grayify(self, image):return image.convert('L')def generate_ascii(self):if not hasattr(self, 'image_path'):returntry:image = Image.open(self.image_path)except Exception as e:print(e)returnimage = self.resize_image(image, new_width=100)image = self.grayify(image)self.ASCII_CHARS = self.ascii_edit.text()if not self.ASCII_CHARS:print('Please input ASCII_CHARS!')returnascii_str = self.pixels_to_ascii(image)img_width = image.widthascii_img = ''for i in range(0, len(ascii_str), img_width):ascii_img += ascii_str[i:i + img_width] + '\n'self.textEdit.setPlainText(ascii_img)def save_ascii(self):if not hasattr(self, 'image_path'):returntry:image = Image.open(self.image_path)except Exception as e:print(e)returnimage = self.resize_image(image, new_width=100)image = self.grayify(image)self.ASCII_CHARS = self.ascii_edit.text()if not self.ASCII_CHARS:print('Please input ASCII_CHARS!')returnascii_str = self.pixels_to_ascii(image)img_width = image.widthascii_img = ''for i in range(0, len(ascii_str), img_width):ascii_img += ascii_str[i:i + img_width] + '\n'options = QFileDialog.Options()fileName, _ = QFileDialog.getSaveFileName(self, "Save ASCII File", "", "Text Files (*.txt)", options=options)if fileName:with open(fileName, 'w') as f:f.write(ascii_img)def pixels_to_ascii(self, image):pixels = image.getdata()ascii_str = ''for pixel in pixels:# 确保灰度值在合理范围内pixel_char = self.ASCII_CHARS[min(len(self.ASCII_CHARS) - 1, pixel // 25)]ascii_str += pixel_charreturn ascii_strdef main():app = QApplication(sys.argv)mainWindow = MainWindow()mainWindow.show()sys.exit(app.exec_())if __name__ == '__main__':main()

 6.效果展示

 自定义设置字符

另存为文本

 

 

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

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

相关文章

多客陪玩系统源码支持二次开发陪玩预约系统搭建,打造专业游戏陪玩平台

简述 随着电竞行业的快速发展,电竞陪玩APP正在逐渐成为用户在休闲娱乐时的首选。为了吸引用户和提高用户体验,电竞陪玩APP开发需要定制一些特色功能,并通过合适的盈利模式来获得收益。本文将为您介绍电竞陪玩APP开发需要定制的特色功能以及常…

LiveCharts2:简单灵活交互式且功能强大的.NET图表库

前言 之前的文章中提到过ScottPlot、与oxyplot,这两个是比较常用的.NET图表库,今天介绍一款新的.NET图表库:LiveCharts2。 LiveCharts2介绍 LiveCharts2 是一个现代化的数据可视化库,用于创建动态和交互式图表,支持…

一小时搞定JavaScript(2)——DOM与BOM的应用

前言,本篇文章是依据bilibili博主(波波酱老师)的学习笔记,波波酱老师讲的很好,很适合速成!!! 本篇文章会与java进行对比学习,因为JS中很多语法和java是相同的,所以大家最好熟悉Java语言后再来进行学习,效果更佳,见效更快. 文章目录 5.DOM和BOM5.1 DOM5.1.1传统元素获取5.1.2 C…

高考志愿填报,是选好专业,还是选好学校?过来人给你说说

分数限制下,选好专业还是选好学校? 到底是先选专业还是先选学校,是让考生及家长一直拿不准、辨不清的问题,是优先考虑学校还是专业,上了好学校,专业不喜欢就业前景不理想,怎么办?为…

【未来已来】AI大模型革命:向量数据库如何重塑智能世界?

在人工智能的浪潮中,向量数据库正成为推动AI大模型发展的幕后英雄。这不是简单的技术升级,而是一场关于智能未来的革命。本文将带您深入了解向量数据库如何成为AI大模型的核心竞争力,以及它如何助力我们在智能化的道路上加速前进。 向量数据库:AI大模型的心脏 想象一下…

vue echarts画多柱状图+多折线图

<!--多柱状图折线图--> <div class"echarts-box" id"multiBarPlusLine"></div>import * as echarts from echarts;mounted() {this.getMultiBarPlusLine() },getMultiBarPlusLine() {const container document.getElementById(multiBar…

图书管理系统代码(Java)

1、运行演示 QQ2024528-205028-HD 详细讲解在这篇博客&#xff1a;JavaSE&#xff1a;图书管理系统-CSDN博客 2、所建的包 3、Java代码 3.1 book包 3.1.1 Book类代码 package book;/*** Created with IntelliJ IDEA.* Description:* User: dings* Date: 2024-05-13* Time:…

押注“人类终极能源”!OpenAI与核聚变公司Helion Energy洽谈“购买大量”聚变能源

内容提要 在当下&#xff0c;由 AI 引发的新一轮能源危机已经不再是一个小概率的“黑天鹅”事件&#xff0c;而是一头正在向我们猛冲而来的“灰犀牛”。 文章正文 Helion Energy&#xff0c;是一家总部位于美国华盛顿州埃弗雷特的能源创业公司。 这家成立于 2013 年的公司在…

安卓实现圆形按钮轮廓以及解决无法更改按钮颜色的问题

1.实现按钮轮廓 在drawable文件新建xml文件 <shape xmlns:android"http://schemas.android.com/apk/res/android"<!--实现圆形-->android:shape"oval"><!--指定内部的填充色--><solid android:color"#FFFFFF"/><!-…

【挑战100天首通《谷粒商城》】-【第一天】06、环境-使用vagrant快速创建linux虚拟机

文章目录 课程介绍1、安装 linux 虚拟机2、安装 VirtualBoxStage 1&#xff1a;开启CPU虚拟化Stage 2&#xff1a;下载 VirtualBoxStage 2&#xff1a;安装 VirtualBoxStage 4&#xff1a;安装 VagrantStage 4-1&#xff1a;Vagrant 下载Stage 4-2&#xff1a;Vagrant 安装Stag…

CentOS 7.9上创建JBOD(一)

系列文章目录 CentOS 7.9上创建的JBOD阵列恢复&#xff08;二&#xff09; CentOS 7.9检测硬盘坏区、实物定位&#xff08;三&#xff09; 文章目录 系列文章目录前言一、安装 mdadm工具二、创建JBOD设备三、为JBOD扩容&#xff08;增加一个硬盘&#xff09;四、最后&#xff…

MySQL修改用户权限(宝塔)

在我们安装好的MySQL中&#xff0c;很可能对应某些操作时&#xff0c;不具备操作的权限&#xff0c;如下是解决这些问题的方法 我以宝塔创建数据库为例&#xff0c;创建完成后&#xff0c;以创建的用户名和密码登录 这里宝塔中容易发生问题的地方&#xff0c;登录不上去&#…

STM32单片机-通信协议(下)

STM32单片机-通信协议(下&#xff09; 一、通信协议介绍二、USART(通用同步/异步收发器)2.1 USART框图和基本结构2.2 串口发送2.2.1 Printf函数移植2.2.2 串口发送汉字 2.3 串口接收2.3.1 串口接收查询2.3.2 串口接收中断 2.4 USART串口数据包2.4.1 数据包格式2.4.2 数据包接收…

企业数字化转型好帮手蚓链,超多创新亮点等你来!

家人们&#xff0c;今天必须给大家分享一下蚓链这个超棒的数字化转型好帮手呀&#xff01; 在理念创新上&#xff0c;它做到了以用户为中心&#xff0c;给大家带来精准化、个性化的营销体验呢。 组织创新也超厉害&#xff0c;搭建了开放式创新平台&#xff0c;吸引外部合作伙伴…

gitlab2024最新版安装

系统&#xff1a;redhat9.0 gitlab版本&#xff1a;gitlab-ce-16.10.7-ce.0.el9.x86_64.rpm 安装组件&包依赖&#xff1a;https://packages.gitlab.com/gitlab/gitlab-ce/packages/ol/9/gitlab-ce-16.10.7-ce.0.el9.x86_64.rpm 参考&#xff1a; 前提&#xff1a; 下载gitl…

石英砂酸洗提纯方法和工艺

石英砂酸洗提纯方法和工艺是石英砂加工中至关重要的一个环节&#xff0c;其目的是通过化学手段去除石英砂中的杂质&#xff0c;提升其纯度。以下将详细介绍石英砂酸洗提纯的方法和工艺&#xff0c;以便更好地理解和应用这一技术。 一、概述 石英砂酸洗提纯主要是利用酸液对石英…

MySQL----表级锁行级锁排它锁和共享锁意向锁

MySQL的锁机制 锁&#xff08;Locking&#xff09;是数据库在并发访问时保证数据一致性和完整性的主要机制。在 MySQL 中&#xff0c;不同存储引擎使用不同的加锁方式&#xff1b;我们以 InnoDB 存储引擎为例介绍 MySQL 中的锁机制&#xff0c;其他存储引擎中的锁相对简单一些…

重大利好!亚马逊推出新功能,跨境商家销量或将迎来大爆发

亚马逊美亚站近日推出的一个新功能——帖子曝光。 顾名思义&#xff0c;帖子曝光这个功能可以提高卖家发布帖子的曝光度&#xff0c;吸引潜在用户&#xff0c;从而提升品牌影响力和产品销量。 亚马逊介绍&#xff0c;帖子曝光功能主要通过将品牌卖家的图文或视频帖子【一键】…

Nginx + KeepAlived高可用负载均衡集群

目录 一、Keepealived脑裂现象 1.现象 2.原因 3.解决 4.预防 二、实验部署 1.两台nginx做初始化操作并安装nginx 2.四层反向代理配置 3.配置高可用 4.准备检查nginx运行状态脚本 5.开启keepalived服务并测试 一、Keepealived脑裂现象 1.现象 主服务器和备服务器都同…

表面声波滤波器——叉指换能器(3)

叉指换能器(interdigital transducers&#xff0c;IDT) 是在压电基片表面激励和检测声表面波&#xff0c;从而实现电信号和声信号间的相互转换。 叉指换能器由在压电基片表面上沉积两组互相交错&#xff0c;周期分布的状金属条带(叉指电极)组成&#xff0c;每组电极和一个汇流…