From 9508c33c8dc4126b1fc9fb342ba6466fdff47c6c Mon Sep 17 00:00:00 2001 From: iFlow CLI Date: Fri, 16 Jan 2026 14:55:53 +0800 Subject: [PATCH] Initial commit: Add image to icon converter application --- Converters.ico | Bin 0 -> 4286 bytes README.md | 43 +++++ SKILL.md | 12 ++ image_to_icon_converter.py | 347 +++++++++++++++++++++++++++++++++++++ 远程仓库地址.txt | 1 + 5 files changed, 403 insertions(+) create mode 100644 Converters.ico create mode 100644 README.md create mode 100644 SKILL.md create mode 100644 image_to_icon_converter.py create mode 100644 远程仓库地址.txt diff --git a/Converters.ico b/Converters.ico new file mode 100644 index 0000000000000000000000000000000000000000..f210eba675bb44cf639d442b21ce2ec138bf29dd GIT binary patch literal 4286 zcmeH}O-NKx6vv;22@x1nR`fB78!IY8qaet_Knx=b26blqSP4PP_A{=8A}457o01~h zw22}L6iUPvQ9F%5N?hos$Si!?=APqVKPpXk-Ozx~#r%$K&xs@X7DVyxh^C zUa+4`CJV`pGA5o4)EMjN=m`Brf#;#j1$#57XZD%XDYL)YHhNdl?ZLhfeJ~+?-*?&M zXPs*C&yu^uZ|3CNhVvwxE?BaUXiUpp)qLdb!8hsW&CoxgW2?3BUJ2;W!=KQ+_4W0| z#Pu2V>SW9~KKYbblLtQU9!edwZ<(ah57ejEs;{%Nv&hU{XJ@kcF?mlx*!LPqJrH&bVAFy4LBhPy2FS2|5`_R0G&L^z*eJ7em+}nTN zU1zmVTk`VWe?8V>3pr1FdH0@y_qdKrEkN$t-UZyHG+*&<%!Wlyb(w xE2X+pN)4ovYQRaVi7}OmOo4B}O{ODmO*)b(PDd6B(h=1K#!?YQY!QpXzX8$spMC%U literal 0 HcmV?d00001 diff --git a/README.md b/README.md new file mode 100644 index 0000000..32f51b3 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# 图片转Icon转换器 + +一个简单易用的GUI应用程序,可以将PNG、JPG、BMP等格式的图片转换为32x32像素的ICO图标文件。 + +## 功能特性 + +- 支持拖放操作,可直接将图片拖拽到应用窗口 +- 支持多种图片格式:PNG、JPG、JPEG、BMP +- 图形化界面,操作简单直观 +- 实时预览转换后的图标 +- 美观的深色主题界面 + +## 使用方法 + +1. 运行程序 +2. 通过以下方式之一加载图片: + - 点击"选择图片"按钮 + - 或直接将图片文件拖拽到窗口中的拖放区域 +3. 点击"转换为Icon"按钮 +4. 选择保存位置和文件名(自动添加.ico扩展名) +5. 转换完成,图标文件已保存 + +## 依赖库 + +- PySide6 + +## 安装依赖 + +```bash +pip install PySide6 +``` + +## 运行程序 + +```bash +python image_to_icon_converter.py +``` + +## 开发信息 + +- 使用Python 3开发 +- 基于PySide6构建GUI界面 +- 转换后的图标大小为32x32像素 \ No newline at end of file diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..985f82c --- /dev/null +++ b/SKILL.md @@ -0,0 +1,12 @@ +## 元数据 +name: pyinstaller个性化打包 +description: 打包的时候,要求生成为一个exe文件,使用ico等等 + +## 概述 +此 Skill 用于给有GUI界面的python代码,打包的时候,生成一个统一的要求:生成一个exe文件,去掉控制台窗口,使用本目录下的ico文件作为程序的图标。打包时,如果之前有打包过的文件(dist/build 文件夹),自动覆盖旧文件,不用手动确认,一键打包到底。 + +## 打包命令示例 +pyinstaller --onefile --noconsole --icon=图标文件名.ico --distpath=. --hidden-import=PySide6.Qt6Compat python程序名.py + +## 清除多余文件 +在windows环境下,删除多余的spec文件、build目录和dist目录 \ No newline at end of file diff --git a/image_to_icon_converter.py b/image_to_icon_converter.py new file mode 100644 index 0000000..2c326a5 --- /dev/null +++ b/image_to_icon_converter.py @@ -0,0 +1,347 @@ +""" +图片转Icon转换器 +支持PNG、BMP、JPEG等格式转换为32x32的ICO格式 +""" + +import sys +from PySide6.QtWidgets import ( + QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, + QPushButton, QLabel, QFileDialog, QGraphicsDropShadowEffect +) +from PySide6.QtCore import Qt, QSize, Signal +from PySide6.QtGui import QPixmap, QIcon, QPalette, QColor, QFont, QDragEnterEvent, QDropEvent +from pathlib import Path + + +class DropArea(QLabel): + """支持拖放的图片显示区域""" + + file_dropped = Signal(str) + + def __init__(self, parent=None): + super().__init__(parent) + self.setAcceptDrops(True) + self.setAlignment(Qt.AlignCenter) + self.setMinimumSize(400, 300) + self.setStyleSheet(""" + QLabel { + background-color: #1a1a2e; + border: 3px dashed #6c5ce7; + border-radius: 16px; + color: #a0a0b0; + font-size: 14px; + padding: 20px; + } + QLabel:hover { + background-color: #242438; + border-color: #8b7ff5; + } + """) + self.setText("🖼️\n\n拖放图片到这里\n或点击下方按钮选择文件\n\n支持 PNG, JPEG, BMP 格式") + + # 添加阴影效果 + shadow = QGraphicsDropShadowEffect() + shadow.setBlurRadius(20) + shadow.setColor(QColor(108, 92, 231, 80)) + shadow.setOffset(0, 4) + self.setGraphicsEffect(shadow) + + def dragEnterEvent(self, event: QDragEnterEvent): + if event.mimeData().hasUrls(): + urls = event.mimeData().urls() + if urls and urls[0].toLocalFile().lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')): + event.acceptProposedAction() + self.setStyleSheet(""" + QLabel { + background-color: #2a2a3e; + border: 3px solid #6c5ce7; + border-radius: 16px; + color: #ffffff; + font-size: 14px; + padding: 20px; + } + """) + + def dragLeaveEvent(self, event): + self.setStyleSheet(""" + QLabel { + background-color: #1a1a2e; + border: 3px dashed #6c5ce7; + border-radius: 16px; + color: #a0a0b0; + font-size: 14px; + padding: 20px; + } + """) + + def dropEvent(self, event: QDropEvent): + files = [u.toLocalFile() for u in event.mimeData().urls()] + if files: + self.file_dropped.emit(files[0]) + self.dragLeaveEvent(event) + + def display_image(self, pixmap: QPixmap): + """显示图片预览""" + scaled_pixmap = pixmap.scaled(380, 280, Qt.KeepAspectRatio, Qt.SmoothTransformation) + self.setPixmap(scaled_pixmap) + self.setStyleSheet(""" + QLabel { + background-color: #1a1a2e; + border: 3px solid #6c5ce7; + border-radius: 16px; + padding: 10px; + } + """) + + +class IconConverterWindow(QMainWindow): + """主窗口""" + + def __init__(self): + super().__init__() + self.current_image_path = None + self.init_ui() + + def init_ui(self): + """初始化UI""" + self.setWindowTitle("图片转Icon转换器") + self.setMinimumSize(600, 800) + + # 设置窗口背景色 + self.setStyleSheet(""" + QMainWindow { + background-color: #0f0f1e; + } + """) + + # 中心部件 + central_widget = QWidget() + self.setCentralWidget(central_widget) + + # 主布局 + main_layout = QVBoxLayout(central_widget) + main_layout.setSpacing(24) + main_layout.setContentsMargins(40, 40, 40, 40) + + # 标题 + title_label = QLabel("图片转Icon转换器") + title_font = QFont("Microsoft YaHei", 28, QFont.Bold) + title_label.setFont(title_font) + title_label.setAlignment(Qt.AlignCenter) + title_label.setStyleSheet("color: #ffffff; margin-bottom: 10px;") + main_layout.addWidget(title_label) + + # 副标题 + subtitle_label = QLabel("将任意图片转换为32×32像素的ICO图标") + subtitle_font = QFont("Microsoft YaHei", 11) + subtitle_label.setFont(subtitle_font) + subtitle_label.setAlignment(Qt.AlignCenter) + subtitle_label.setStyleSheet("color: #a0a0b0; margin-bottom: 20px;") + main_layout.addWidget(subtitle_label) + + # 拖放区域 + self.drop_area = DropArea() + self.drop_area.file_dropped.connect(self.load_image) + main_layout.addWidget(self.drop_area) + + # 按钮容器 + button_layout = QHBoxLayout() + button_layout.setSpacing(16) + + # 选择文件按钮 + self.select_btn = QPushButton("📁 选择图片") + self.select_btn.setMinimumHeight(50) + self.select_btn.setCursor(Qt.PointingHandCursor) + self.select_btn.setStyleSheet(""" + QPushButton { + background-color: #6c5ce7; + color: white; + border: none; + border-radius: 12px; + font-size: 15px; + font-weight: bold; + padding: 12px 24px; + } + QPushButton:hover { + background-color: #7c6cf7; + } + QPushButton:pressed { + background-color: #5c4cd7; + } + """) + self.select_btn.clicked.connect(self.select_file) + button_layout.addWidget(self.select_btn) + + # 转换按钮 + self.convert_btn = QPushButton("✨ 转换为Icon") + self.convert_btn.setMinimumHeight(50) + self.convert_btn.setCursor(Qt.PointingHandCursor) + self.convert_btn.setEnabled(False) + self.convert_btn.setStyleSheet(""" + QPushButton { + background-color: #00d4aa; + color: white; + border: none; + border-radius: 12px; + font-size: 15px; + font-weight: bold; + padding: 12px 24px; + } + QPushButton:hover:enabled { + background-color: #00e4ba; + } + QPushButton:pressed:enabled { + background-color: #00c49a; + } + QPushButton:disabled { + background-color: #2a2a3e; + color: #5a5a6e; + } + """) + self.convert_btn.clicked.connect(self.convert_to_icon) + button_layout.addWidget(self.convert_btn) + + main_layout.addLayout(button_layout) + + # 预览区域 + preview_container = QWidget() + preview_container.setStyleSheet(""" + QWidget { + background-color: #1a1a2e; + border-radius: 16px; + padding: 20px; + } + """) + preview_layout = QVBoxLayout(preview_container) + + preview_title = QLabel("转换后预览 (32×32)") + preview_title.setFont(QFont("Microsoft YaHei", 12, QFont.Bold)) + preview_title.setStyleSheet("color: #ffffff; margin-bottom: 10px;") + preview_title.setAlignment(Qt.AlignCenter) + preview_layout.addWidget(preview_title) + + self.preview_label = QLabel() + self.preview_label.setAlignment(Qt.AlignCenter) + self.preview_label.setMinimumHeight(100) + self.preview_label.setStyleSheet(""" + QLabel { + background-color: #0f0f1e; + border-radius: 12px; + padding: 20px; + } + """) + self.preview_label.setText("等待转换...") + self.preview_label.setStyleSheet(self.preview_label.styleSheet() + "color: #6a6a7e;") + preview_layout.addWidget(self.preview_label) + + main_layout.addWidget(preview_container) + + # 状态标签 + self.status_label = QLabel("准备就绪") + self.status_label.setAlignment(Qt.AlignCenter) + self.status_label.setStyleSheet("color: #6c5ce7; font-size: 13px; margin-top: 10px;") + main_layout.addWidget(self.status_label) + + # 添加弹性空间 + main_layout.addStretch() + + def select_file(self): + """选择文件对话框""" + file_path, _ = QFileDialog.getOpenFileName( + self, + "选择图片文件", + "", + "图片文件 (*.png *.jpg *.jpeg *.bmp);;所有文件 (*.*)" + ) + + if file_path: + self.load_image(file_path) + + def load_image(self, file_path: str): + """加载图片""" + self.current_image_path = file_path + pixmap = QPixmap(file_path) + + if pixmap.isNull(): + self.status_label.setText("❌ 无法加载图片") + self.status_label.setStyleSheet("color: #ff6b6b; font-size: 13px;") + return + + self.drop_area.display_image(pixmap) + self.convert_btn.setEnabled(True) + + file_name = Path(file_path).name + self.status_label.setText(f"✅ 已加载: {file_name}") + self.status_label.setStyleSheet("color: #00d4aa; font-size: 13px;") + + # 清除预览 + self.preview_label.clear() + self.preview_label.setText("等待转换...") + self.preview_label.setStyleSheet("color: #6a6a7e; background-color: #0f0f1e; border-radius: 12px; padding: 20px;") + + def convert_to_icon(self): + """转换为Icon""" + if not self.current_image_path: + return + + # 加载原始图片 + original_pixmap = QPixmap(self.current_image_path) + + # 缩放到32x32 + icon_pixmap = original_pixmap.scaled( + 32, 32, + Qt.KeepAspectRatio, + Qt.SmoothTransformation + ) + + # 保存对话框 + save_path, _ = QFileDialog.getSaveFileName( + self, + "保存Icon文件", + str(Path(self.current_image_path).stem) + ".ico", + "Icon文件 (*.ico);;所有文件 (*.*)" + ) + + if save_path: + # 保存为ICO格式 + icon = QIcon(icon_pixmap) + icon_pixmap.save(save_path, "ICO") + + # 更新预览 - 放大显示以便查看 + preview_pixmap = icon_pixmap.scaled( + 64, 64, + Qt.KeepAspectRatio, + Qt.FastTransformation + ) + self.preview_label.setPixmap(preview_pixmap) + self.preview_label.setStyleSheet("background-color: #0f0f1e; border-radius: 12px; padding: 20px;") + + self.status_label.setText(f"🎉 转换成功! 已保存到: {Path(save_path).name}") + self.status_label.setStyleSheet("color: #00d4aa; font-size: 13px;") + + +def main(): + app = QApplication(sys.argv) + + # 设置应用样式 + app.setStyle("Fusion") + + # 设置深色调色板 + palette = QPalette() + palette.setColor(QPalette.Window, QColor(15, 15, 30)) + palette.setColor(QPalette.WindowText, Qt.white) + palette.setColor(QPalette.Base, QColor(26, 26, 46)) + palette.setColor(QPalette.AlternateBase, QColor(31, 31, 51)) + palette.setColor(QPalette.Text, Qt.white) + palette.setColor(QPalette.Button, QColor(108, 92, 231)) + palette.setColor(QPalette.ButtonText, Qt.white) + app.setPalette(palette) + + window = IconConverterWindow() + window.show() + + sys.exit(app.exec()) + + +if __name__ == "__main__": + main() diff --git a/远程仓库地址.txt b/远程仓库地址.txt new file mode 100644 index 0000000..fc4d227 --- /dev/null +++ b/远程仓库地址.txt @@ -0,0 +1 @@ +http://14.103.237.41:16001/xiaji/image2icon.git \ No newline at end of file