348 lines
12 KiB
Python
348 lines
12 KiB
Python
"""
|
||
图片转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()
|