PyQt5开发简单的图片转换器,将图片格式转换为webp格式

1、准备

(1)在项目下创建python虚拟环境及安装PyQt5:

# 创建python虚拟环境
python -m venv venv

# 在虚拟环境中安装PyQt5
pip install PyQt5

(2)Webp工具下载: webp下载地址

2、Webp介绍

WebP 是 Google 开发的图片格式,其设计目标是提高图片质量,降低图片大小。

Webp介绍

3、简单图片转换器开发

(1)开发这个工具的原因

个人博客网站经常使用图片,在博客网站上,图片的大小和格式都比较重要。

与其他格式图片对比发现,Webp格式图片的压缩率高,图片质量高,图片大小小,所以使用Webp格式图片。

其他格式图片转换为webp格式需要使用Webp转换工具,这个工具只是命令行操作,需要经常手动复制路径,很麻烦。

所以我就使用PyQt5简单的封装下制作一个简单的界面操作小工具,方便自己操作。

(2)项目结构

项目结构

(3)界面设计 界面设计

使用QtDesigner设计的界面虽然有点Low,但是可以满足基本需求的界面化操作,不必总是在命令行里复制、粘贴输入和输出路径参数。

(4)文件转换

  • ui文件转换为python文件

这步操作是最简单的,只需之前配置好的辅助工具Pyuic,点几下就可以,每次ui文件修改了只需这么简单操作一下,就可以完成python文件的转换,使用方法如下:

ui文件转换为python文件
  • qrc文件转换为python文件

项目中暂时没有资源文件,这个就无需操作了,使用方法与ui文件转换一样。

(5)启动程序

启动方式有两种:一种是直接加载ui文件启动,另一种是将ui文件转换为python文件启动。

因为我使用了辅助工具Pyuic,每次修改ui文件后再编译为python文件非常方便,基本上我都采用将ui文件转换为python文件启动。

  • 启动方式一:直接加载ui文件启动
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QWidget

class ImgWidget(QWidget):

    def __init__(self):
        super().__init__()
        uic.loadUi("imgToWebp.ui", self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    img = ImgWidget()
    img.show()
    sys.exit(app.exec_())
  • 启动方式二:将ui文件转换为python文件启动
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from imgToWebp import Ui_Form

class ImgWidget(QWidget,Ui_Form):

    def __init__(self):
        super().__init__()
        self.setupUi(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    img = ImgWidget()
    img.show()
    sys.exit(app.exec_())
  • 启动后界面
启动后界面
  • 两种启动方式区别

直接加载ui文件启动需要导入uic模块,然后调用loadUi方法

将ui文件转换为python文件启动需要导入转换的python文件和继承自动编译的界面类名(Ui_Form),然后调用setupUi方法

两种方法都需要继承QWidget,因为我的ui界面文件是QWidget,那就需要继承 QWidget;

ui界面文件是QWidget

注:

  • 如果ui界面文件是Widget,那就需要继承 QWidget。
  • 如果ui界面文件是MainWindow,那就需要继承 QMainWindow。
  • 如果ui界面文件是Dialog,那就需要继承QDialog。

4、功能实现

(1)shell脚本路径选择

为什么会有shell脚本,是因为Webp工具是都是命令行操作,通过shell脚本整合里面所有功能,然后通过输入参数和输出参数实现批量转换。

目前只是实现了两个功能:

  • cwebp:将其他图片转换为 WebP
  • gif2webp:将GIF图片转换为 WebP

(2)输入文件夹或者文件路径选择

当选择文件夹时,会将该文件夹下所有图片都进行转换,

当选择文件时,会将选择的文件进行转换。

(3)输出文件夹路径选择

(4)说明

这个功能是将Webp这个工具里面的功能进行展示,方便自己完善shell脚本中其他功能的实现。

libwebp功能说明

(5)完整代码

import sys
import os
import subprocess
from PyQt5.QtWidgets import QApplication, QWidget, QFileDialog
from imgToWebp import Ui_Form
from PyQt5.QtWebEngineWidgets import QWebEngineView

def setLineText(line, path):
    if path == '':
        pass
    else:
        line.setText(path)

class ImgWidget(QWidget, Ui_Form):

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.current_path = os.path.split(os.path.realpath(__file__))[0]

        # 脚本
        self.setShell()
        # 输入
        self.inputDir.toggled.connect(self.inputType)
        self.inputFile.toggled.connect(self.inputType)
        self.setInput()
        # 输出
        self.setOutput()
        self.startBtn.clicked.connect(self.imgToWebp)

        # 说明
        self.libwebp = self.current_path + "/libwebp"
        self.descBtn.clicked.connect(self.libwebpDesc)

    # 脚本
    def setShell(self):
        self.shellLine.setText(self.current_path + "/imgToWebp.sh")
        self.shellBtn.clicked.connect(self.openShellFileDialog)

    def openShellFileDialog(self):
        path, _ = QFileDialog.getOpenFileName(self, "选择文件", ".", "*.sh")
        setLineText(self.shellLine, path)

    # 输入
    def inputType(self):
        if self.inputDir.isChecked():
            self.inputBtn.setText("选择文件夹")
        elif self.inputFile.isChecked():
            self.inputBtn.setText("选择文件")
        else:
            print("请选择一个")
    def setInput(self):
        self.inputBtn.clicked.connect(self.openInputFileDialog)

    def openInputFileDialog(self):
        if self.inputFile.isChecked():
            path, _ = QFileDialog.getOpenFileName(self, "选择文件", "/", "*.png;*.jpg;*.jpeg;*.gif")
            setLineText(self.inputLine, path)

        elif self.inputDir.isChecked():
            path = QFileDialog.getExistingDirectory(self, "选择文件夹", "/")
            setLineText(self.inputLine, path)
        else:
            print("请选择一个")

    # 输出
    def setOutput(self):
        self.outputBtn.clicked.connect(self.openOutputFileDialog)

    def openOutputFileDialog(self):
        path = QFileDialog.getExistingDirectory(self, "选择文件夹", "/")
        setLineText(self.outputLine, path)

    # 执行转换
    def imgToWebp(self):
        script_path = self.shellLine.text()
        args = [self.inputLine.text(), self.outputLine.text(),self.libwebp]
        try:
            # 调用Shell命令并传递参数
            result = subprocess.run([script_path] + args, capture_output=True, text=True)

            if result.returncode == 0:
                print("Shell脚本执行成功!")

                # 输出Shell脚本的标准输出结果
                print(result.stdout)
            else:
                print("Shell脚本执行失败!")
        except FileNotFoundError as e:
            print("无法找到指定的Shell脚本文件!错误信息:%s" % str(e))
        except Exception as e:
            print("发生了未知错误:%s" % str(e))

    def libwebpDesc(self):

        import libwebpDesc
        self.page = libwebpDesc.LibWebpDesc()
        self.page.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    img = ImgWidget()
    img.show()
    sys.exit(app.exec_())

自己使用的小工具,没啥样式,后期会慢慢进行优化迭代。