【ICO/WMF】PNG/JPEG转ICO/WMF工具
工具介绍
工具名称:图形转换工具
工具版本:1.03
功能介绍:
1.支持PNG、JPEG格式转为ICO图标或WMF格式图片
2.可以选择单个图形文件,也可以选择图形文件夹进行批量处理
3.可以选择常见尺寸、倍率、自定义宽和高对ICO图标和WMF图片进行缩放
工具截图:
下载链接:GitHub下载地址 百度网盘下载地址
源代码:
import PIL.Image as im
import tkinter.filedialog as tf
import tkinter as tk
import tkinter.messagebox as tm
import random
import os
from sys import executable as EXECUTABLE
from win32api import SetFileAttributes
from win32con import FILE_ATTRIBUTE_HIDDEN
from subprocess import Popen, PIPE, STDOUT
import Tool.PackTool as pt
from Tool.ico import ico1
import Tool.MyLogger as ml
from ctypes import windllclass ToIco:__filePath = ''__foderPath = ''__cWidth = 16__cHeight = 16__sizeMode = 0__imgType = '.ico'__tips = ('生成的图形文件保存地址为所选PNG或JPG文件所在地址', '可以处理单个文件也可以处理多个文件', '处理图形文件夹时仅处理PNG和JPG文件', '当存在同名图形文件时会覆盖已存在的图形文件')__site = [('单个图形文件', 0), ('图形文件夹', 1)]__type = [('.ico', 0), ('.wmf', 1)]__rotation = [('0.5倍', 0), ('原比例', 1), ('1.5倍', 2), ('2倍', 3), ('3倍', 4), ('5倍', 5)]__choice = [('尺寸转换', 0), ('缩放比例', 1), ('自定义宽和高', 2)]__isDefineCb = True__log = ml.IMyLogger()def _windowSize(self, p_width, p_height):size = '%dx%d+%d+%d' % (p_width, p_height, (self.__screenWidth - p_width) / 2, (self.__screenHeight - p_height) / 2)return size# 创建快捷方式def _createShortcut(self):execpath = os.path.dirname(EXECUTABLE)batpath = execpath + "\\init.bat"if os.path.exists(batpath):self.__log.InLog("Create shortcut successful!")startcmd = "start " + "shortcut.bat"startpath = execpath + "\\shortcut.bat"cmd = "cd " + execpath + " && " + startcmdpop = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)pop.wait()if pop.returncode == 0:pop.terminate()pop.kill()SetFileAttributes(startpath, FILE_ATTRIBUTE_HIDDEN)def __init__(self):self._createShortcut()# 告诉操作系统使用程序自身的dpi适配windll.shcore.SetProcessDpiAwareness(1)# 获取屏幕的缩放因子ScaleFactor = windll.shcore.GetScaleFactorForDevice(0)self.__cPIPT = pt.IPackTool(False)self.__root = tk.Tk()self.__root.title('图形转换工具')# 获取屏幕宽高self.__screenWidth = self.__root.winfo_screenwidth()self.__screenHeight = self.__root.winfo_screenheight()# 设置窗口大小self.__root.geometry(self._windowSize(int(self.__screenWidth * 0.35), int(self.__screenHeight * 0.625)))self.__root.wm_minsize(int(self.__screenWidth * 0.31), int(self.__screenHeight * 0.56))self.__cPIPT.IcoBase64Decoder('icoTool', ico1)self.__cPIPT.IcoSetToTk(self.__root, 'icoTool')# 设置程序缩放self.__root.tk.call('tk', 'scaling', ScaleFactor / 75)self.__v = tk.IntVar()self.__r = tk.IntVar()self.__c = tk.IntVar()self.__t = tk.IntVar()self.__check1 = tk.IntVar()self.__check2 = tk.IntVar()self.__check3 = tk.IntVar()self.__check4 = tk.IntVar()self.__check5 = tk.IntVar()self.__check6 = tk.IntVar()self.__sizeCheck = [('16x16', self.__check1), ('32x32', self.__check2), ('48x48', self.__check3),('64x64', self.__check4), ('128x128', self.__check5), ('256x256', self.__check6)]self.__Fr_m = tk.Frame(self.__root, pady='10px')self.__Fr_m.pack(expand='yes')self.__Fr_1 = tk.Frame(self.__Fr_m)self.__Lb_1 = tk.Label(self.__Fr_1, text='请选择图形文件或图形文件夹', font=('幼圆', 9, 'bold'), fg='red')self.__Lb_1.pack(expand='yes', pady='5px')for name, index in self.__site:Rb = tk.Radiobutton(self.__Fr_1, text=name, font=('幼圆', 9, 'bold'), variable=self.__v, value=index,command=lambda: self._ClearPath())Rb.pack(expand='yes')self.__Bt_1 = tk.Button(self.__Fr_1, text='选择文件或文件夹', font=('幼圆', 9, 'bold'), width=20,command=lambda: self._ChooseMode(self.__v.get()))self.__Bt_1.pack(expand='yes', pady='5px')self.__Fr_1_1 = tk.Frame(self.__Fr_1)self.__Lb_9 = tk.Label(self.__Fr_1_1, text='请选择待转换图形文件的格式', font=('幼圆', 9, 'bold'), fg='red')self.__Lb_9.pack(expand='yes', pady='5px')for name, index in self.__type:Rb = tk.Radiobutton(self.__Fr_1_1, text=name, font=('幼圆', 9, 'bold'), variable=self.__t, value=index,command=lambda: self._ImageTypeChange(self.__t.get()))Rb.pack(expand='yes', padx='5px', side='left')self.__Fr_1_1.pack(expand='yes', pady='5px')self.__Lb_2 = tk.Label(self.__Fr_1, font=('幼圆', 9, 'bold'), foreground='blue', text='')self.__Lb_2.pack(expand='yes', pady='5px')for name, index in self.__choice:Rb = tk.Radiobutton(self.__Fr_1, text=name, font=('幼圆', 9, 'bold'), variable=self.__c, value=index,command=lambda: self._FrameActive(self.__c.get()))Rb.pack(expand='yes', padx='5px', side='left')self.__Fr_1.pack(expand='yes', pady='5px')self.__Fr_2 = tk.Frame(self.__Fr_m)self.__Lb_3 = tk.Label(self.__Fr_2, font=('幼圆', 9, 'bold'), text='请选择转换后的图形文件尺寸', fg='red')self.__Lb_3.pack(expand='yes', pady='5px')for name, vari in self.__sizeCheck:Cb = tk.Checkbutton(self.__Fr_2, text=name, font=('幼圆', 9, 'bold'), variable=vari,command=lambda: self._RandomTip())Cb.pack(expand='yes')if self.__isDefineCb:Cb.select()self.__isDefineCb = Falseself.__Fr_2.pack(expand='yes')self.__Fr_3 = tk.Frame(self.__Fr_m)self.__Lb_4 = tk.Label(self.__Fr_3, text='请选择转换后的图形文件缩放比例', font=('幼圆', 9, 'bold'), fg='red')self.__Lb_4.pack(expand='yes', pady='5px')for name, index in self.__rotation:Rb = tk.Radiobutton(self.__Fr_3, text=name, font=('幼圆', 9, 'bold'), variable=self.__r, value=index,command=lambda: self._RandomTip())Rb.pack(expand='yes')self.__Fr_3.pack_forget()self.__Fr_4 = tk.Frame(self.__Fr_m)self.__Lb_5 = tk.Label(self.__Fr_4, text='请输入转换后的图形文件宽和高', font=('幼圆', 9, 'bold'), fg='red')self.__Lb_5.pack(expand='yes', pady='5px')self.__Fr_4_1 = tk.Frame(self.__Fr_4)self.__Lb_5 = tk.Label(self.__Fr_4_1, text='Width:', font=('幼圆', 9, 'bold'))self.__Lb_5.pack(expand='yes', side='left')self.__Et1_R = self.__root.register(self._CallBack)self.__Et_1 = tk.Entry(self.__Fr_4_1, validate='focus', validatecommand=(self.__Et1_R, "%P"))self.__Et_1.pack(expand='yes', side='left')self.__Fr_4_1.pack(expand='yes', pady='5px')self.__Fr_4_2 = tk.Frame(self.__Fr_4)self.__Lb_6 = tk.Label(self.__Fr_4_2, text='Height:', font=('幼圆', 9, 'bold'))self.__Lb_6.pack(expand='yes', side='left')self.__Et2_R = self.__root.register(self._CallBack)self.__Et_2 = tk.Entry(self.__Fr_4_2, validate='focus', validatecommand=(self.__Et2_R, "%P"))self.__Et_2.pack(expand='yes', side='left')self.__Fr_4_2.pack(expand='yes', pady='5px')self.__Fr_4.pack_forget()self.__Lb_7 = tk.Label(self.__Fr_4, text='', fg='red', font=('幼圆', 9, 'bold'))self.__Lb_7.pack_forget()self.__Bt_1 = tk.Button(self.__root, text='转换', font=('幼圆', 9, 'bold'), width=20, command=lambda: self._Run())self.__Bt_1.pack(expand='yes', pady='5px')self.__Lb_8 = tk.Label(self.__root, text='Tip:生成的图形转换文件保存地址为所选PNG或JPG文件所在地址', fg='red', font=('幼圆', 9, 'bold'))self.__Lb_8.pack(expand='yes', pady='5px', side='bottom')self.__root.mainloop()def _ClearPath(self):self.__filePath = ""self.__foderPath = ""self.__Lb_2.config(text="")self._RandomTip()def _Run(self):if self.__filePath == '' and self.__foderPath == '':tm.showinfo('提示', '请选择文件或文件夹')self._RandomTip()if self.__c.get() == 2:if self._CustomValueCheck() is True:self._Transform(self.__filePath, self.__foderPath)else:if self._ValueCheck() is True:self._Transform(self.__filePath, self.__foderPath)def _CallBack(self, p_value):p_value = Noneself._RandomTip()return Truedef _RandomTip(self):i = random.randint(0, len(self.__tips) - 1)self.__Lb_8.config(text='Tip:' + self.__tips[i])self.__root.update()def _ChooseMode(self, p_index):self._RandomTip()if p_index == 0:self.__filePath = tf.askopenfilename()self.__foderPath = ''self.__Lb_2.config(text=self.__filePath)if p_index == 1:self.__foderPath = tf.askdirectory()self.__filePath = ''self.__Lb_2.config(text=self.__foderPath)def _GetCheckButtonValue(self):v_vari = [self.__check1, self.__check2, self.__check3, self.__check4, self.__check5, self.__check6]v_values = []for i in range(6):v_values.append((i, v_vari[i].get()))return v_valuesdef _ChooseSize(self, img, i):if i == 0:return self._Resize(img, self._GetCheckButtonValue())elif i == 1:return self._RotateSize(img, self.__r.get())elif i == 2:return self._CustomSize(img)def _ImageTypeChange(self, i):self._RandomTip()if i == 0:self.__imgType = '.ico'else:self.__imgType = '.wmf'def _FrameActive(self, i):self.__sizeMode = iself._RandomTip()if i == 0:self.__Fr_2.pack()self.__Fr_3.pack_forget()self.__Fr_4.pack_forget()self.__root.update()elif i == 1:self.__Fr_3.pack()self.__Fr_2.pack_forget()self.__Fr_4.pack_forget()self.__root.update()elif i == 2:self.__Fr_4.pack()self.__Fr_2.pack_forget()self.__Fr_3.pack_forget()self.__root.update()# 图形转换def _Transform(self, p_filePath, p_foderPath):if p_filePath != '':a = im.open(p_filePath)v_imgs = self._ChooseSize(a, self.__sizeMode)v_isNull = Falseif self.__sizeMode == 0 and (v_imgs is None or len(v_imgs) == 0):tm.showwarning('Warning', '请选择图形尺寸!')self._RandomTip()v_isNull = Truev_name = p_filePath.split('/')[-1].split('.')imageName = v_name[0]suffixName = v_name[-1]if (suffixName == 'png' or suffixName == 'jpg') and not v_isNull:v_path = p_filePath.replace(p_filePath.split('/')[-1], "")i = 1v_imageInfos = []if self.__sizeMode == 0:for v_img in v_imgs:v_filePath = v_path + imageName + str(i) + '.bmp'v_imageInfos.append((imageName + str(i), v_filePath))v_img.save(v_filePath)i += 1else:v_filePath = v_path + imageName + str(i) + '.bmp'v_imageInfos.append((imageName + str(i), v_filePath))v_imgs.save(v_filePath)try:for v_imageName, v_filePath in v_imageInfos:n_filePath = v_path + v_imageName + self.__imgTypeif not os.path.exists(n_filePath):os.rename(v_filePath, n_filePath)else:os.remove(n_filePath)os.rename(v_filePath, n_filePath)except FileNotFoundError:tm.showerror('错误', '文件不存在')self._RandomTip()else:self.__Lb_8.config(text='转换成功')self.__Lb_8.pack(pady='5px', side='bottom')elif p_foderPath != '':files = os.listdir(p_foderPath)isSuccess = Falsev_isNull = Truev_values = self._GetCheckButtonValue()for i, v in v_values:if v == 1:v_isNull = Falseif not v_isNull:for img in files:path = p_foderPath + '/' + imgv_name = path.split('/')[-1].split('.')imageName = v_name[0]suffixName = v_name[-1]if suffixName == 'png' or suffixName == 'jpg':a = im.open(path)v_imgs = self._ChooseSize(a, self.__sizeMode)v_path = path.replace(path.split('/')[-1], "")i = 1v_imageInfos = []for v_img in v_imgs:v_filePath = v_path + imageName + str(i) + '.bmp'v_imageInfos.append((imageName + str(i), v_filePath))v_img.save(v_filePath)i += 1try:for v_imageName, v_filePath in v_imageInfos:n_filePath = v_path + v_imageName + self.__imgTypeif not os.path.exists(n_filePath):os.rename(v_filePath, n_filePath)else:os.remove(n_filePath)os.rename(v_filePath, n_filePath)except FileNotFoundError:tm.showerror('错误', '文件不存在')self._RandomTip()isSuccess = Falseelse:isSuccess = Trueif isSuccess is True:self.__Lb_8.config(text='转换成功')self.__Lb_8.pack(pady='5px', side='bottom')def _Resize(self, img, p_values):width, height = img.sizev_imgs = []if width == height:for i, value in p_values:if value == 1:if i == 0:v_imgs.append(img.resize((16, 16), im.Resampling.LANCZOS))elif i == 1:v_imgs.append(img.resize((32, 32), im.Resampling.LANCZOS))elif i == 2:v_imgs.append(img.resize((48, 48), im.Resampling.LANCZOS))elif i == 3:v_imgs.append(img.resize((64, 64), im.Resampling.LANCZOS))elif i == 4:v_imgs.append(img.resize((128, 128), im.Resampling.LANCZOS))elif i == 5:v_imgs.append(img.resize((256, 256), im.Resampling.LANCZOS))elif width > height:for i, value in p_values:if value == 1:if i == 0:v_height = int((16 / width) * height)v_imgs.append(img.resize((16, v_height), im.Resampling.LANCZOS))elif i == 1:v_height = int((32 / width) * height)v_imgs.append(img.resize((32, v_height), im.Resampling.LANCZOS))elif i == 2:v_height = int((48 / width) * height)v_imgs.append(img.resize((48, v_height), im.Resampling.LANCZOS))elif i == 3:v_height = int((64 / width) * height)v_imgs.append(img.resize((64, v_height), im.Resampling.LANCZOS))elif i == 4:v_height = int((128 / width) * height)v_imgs.append(img.resize((128, v_height), im.Resampling.LANCZOS))elif i == 5:v_height = int((256 / width) * height)v_imgs.append(img.resize((256, v_height), im.Resampling.LANCZOS))else:for i, value in p_values:if value == 1:if i == 0:v_width = int((16 / height) * width)v_imgs.append(img.resize((v_width, 16), im.Resampling.LANCZOS))elif i == 1:v_width = int((32 / height) * width)v_imgs.append(img.resize((v_width, 32), im.Resampling.LANCZOS))elif i == 2:v_width = int((48 / height) * width)v_imgs.append(img.resize((v_width, 48), im.Resampling.LANCZOS))elif i == 3:v_width = int((64 / height) * width)v_imgs.append(img.resize((v_width, 64), im.Resampling.LANCZOS))elif i == 4:v_width = int((128 / height) * width)v_imgs.append(img.resize((v_width, 128), im.Resampling.LANCZOS))elif i == 5:v_width = int((256 / height) * width)v_imgs.append(img.resize((v_width, 256), im.Resampling.LANCZOS))return v_imgsdef _RotateSize(self, img, p_size):width, height = img.sizeif p_size == 0:v_size = (int(width * 0.5), int(height * 0.5))return img.resize(v_size, im.Resampling.LANCZOS)elif p_size == 1:v_size = (int(width), int(height))return img.resize(v_size, im.Resampling.LANCZOS)elif p_size == 2:v_size = (int(width * 1.5), int(height * 1.5))return img.resize(v_size, im.Resampling.LANCZOS)elif p_size == 3:return img.resize((width * 2, height * 2), im.Resampling.LANCZOS)elif p_size == 4:return img.resize((width * 3, height * 3), im.Resampling.LANCZOS)elif p_size == 5:return img.resize((width * 4, height * 4), im.Resampling.LANCZOS)def _CustomSize(self, img):return img.resize((self.__cWidth, self.__cHeight), im.Resampling.LANCZOS)# 选择文件检测def _ValueCheck(self):v_filePath = self.__filePathif v_filePath != '':v_fileSuffix = v_filePath.split('/')[-1].split('.')[-1]if v_fileSuffix == 'png' or v_fileSuffix == 'jpg':return Trueelse:tm.showwarning('Warning', '请选择PNG或JPG文件!')self.__filePath = ''self.__Lb_2.config(text='')self._RandomTip()return Falseelse:return True# 自定义宽高输入检测def _CustomValueCheck(self):self.__Lb_7.pack_forget()if self.__filePath != "" or self.__foderPath != "":v_i = 3try:pwidth = str(self.__Et_1.get()).strip()pheight = str(self.__Et_2.get()).strip()if pwidth == '' or pheight == '':width = 16height = 16self.__Lb_7.config(text='你输入的数据为空')self.__Lb_7.pack(pady='5px', side='bottom')self._RandomTip()self.__root.update()else:v_i = 0width = int(pwidth)widthInfo = (width, True) if width > 0 else (1, False)print(widthInfo[0])if not widthInfo[1]:tm.showwarning("Warning", "Width不能为负数!")returnwidth = widthInfo[0]widthInfo = (width, True) if width <= 3840 else (3840, False)width = widthInfo[0]if not widthInfo[1]:tm.showwarning("Warning", "Width不能大于3840!")returnv_i = 1height = int(pheight)heightInfo = (height, True) if height > 0 else (1, False)if not heightInfo[1]:tm.showwarning("Warning", "Height不能为负数!")returnheight = heightInfo[0]heightInfo = (height, True) if height <= 2048 else (2048, False)if not heightInfo[1]:tm.showwarning("Warning", "Height不能大于2048!")returnheight = heightInfo[0]v_i = 2except ValueError:if v_i == 0:self.__Lb_7.config(text='你输入的Width的数据存在类型错误,请输入整数')elif v_i == 1:self.__Lb_7.config(text='你输入的Height的数据存在类型错误,请输入整数')self.__Lb_7.pack(pady='5px', side='bottom')self._RandomTip()self.__root.update()return Falseelse:if v_i == 2:self.__Lb_7.pack_forget()self.__Lb_8.config(text='转换成功')self.__Lb_8.pack(pady='5px', side='bottom')self.__cWidth = widthself.__cHeight = heightreturn Trueclass IToIco:def __init__(self):self.__ti = ToIco()cTITI = IToIco()
免责声明:由于本文内容未经过正规和严格的测试,可能存在错误,因此造成的损失均由使用者自行承担,对本文内容复制、下载、参考等引用行为即默认悉知并同意该声明。
如果这篇文章对你有帮助,请给作者点个赞吧!