Рубрики
Без рубрики

Как построить простой инструмент преобразования WebP с Python, Qt и Opencv

«WebP – это формат изображения, использующий как сжатие с потерями, так и без потерь, и поддерживает анимацию и … Помечено webp, python, Qt, openc.

«WebP – это формат изображения, использующий как сжатие с потерями, так и без потерь, и поддерживает анимацию и прозрачность альфа. Разработанный Google, он предназначен для создания файлов, которые меньше для того же качества, или более высокого качества для того же размера, чем форматы IPEG, PNG и GIF, – Wikipedia . Скорость является одним из ключевых факторов оптимизации SEO. Разработчики имеют тенденцию использовать WebP для замены JPEG, PNG и GIF, чтобы сделать веб-страницы SEO дружелюбным. Эта статья демонстрирует, как построить простой инструмент преобразования WebP с Python, Qt и OpenCV.

Установка

Разработка инструмента преобразования WebP

Шаг 1: Проектирование макета и загрузить UI в код Python

Давайте откроем Python/lib/сайт-пакеты/pyside2/дизайнер разработать графический интерфейс.

  • Этикетка: Отображение загруженного изображения.
  • Горизонтальный слайдер: отрегулируйте качество изображения WebP.
  • Нажмите кнопку: триггерное преобразование WebP.
  • Список виджет: добавьте файлы изображений в список.

Как только дизайн пользовательского интерфейса будет конвертировать .ui Файл к .py Файл с использованием Pyside2-UIC , который находится в Python/Scripts/ Отказ

pyside2-uic design.ui -o design.py

Следующий шаг – загрузить Design.py Файл и добавьте следующий код на main.py файл:

import sys
from PySide2.QtGui import QPixmap, QImage, QPainter, QPen, QColor
from PySide2.QtWidgets import QApplication, QMainWindow, QInputDialog
from PySide2.QtCore import QFile, QTimer, QEvent
from PySide2.QtWidgets import *
from design import Ui_MainWindow

import os
import cv2

from PySide2.QtCore import QObject, QThread, Signal

class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.setAcceptDrops(True)

def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

Теперь, работает main.py Файл покажет графический интерфейс.

Шаг 2: Загрузите файлы изображений для списка виджетов и отображения изображений

Есть два способа загрузить файл изображения или папку:

  • Нажмите кнопку, чтобы открыть диалоговое окно «Системный файл».
  • Перетащите файл изображения или папку в приложение.

Чтобы открыть диалоговое окно «Системный файл», мы используем Qfiledialog , который обеспечивает getopenfilename выбрать файл и GetExistingDirectory выбрать каталог.

self.ui.actionOpen_File.triggered.connect(self.openFile)
self.ui.actionOpen_Folder.triggered.connect(self.openFolder)

def openFile(self):
    filename = QFileDialog.getOpenFileName(self, 'Open File',
                                            self._path, "Barcode images (*)")

def openFolder(self):
    directory = QFileDialog.getExistingDirectory(self, 'Open Folder',
                                            self._path, QFileDialog.ShowDirsOnly)

Чтобы включить перетаскивание для файла и папки, мы должны установить setacceptdrops (true) для Главный и переопределить Драчантировать и Dropevent Методы:

def __init__(self):
    # ...
    self.setAcceptDrops(True)

def dragEnterEvent(self, event):
    event.acceptProposedAction()

def dropEvent(self, event):
    urls = event.mimeData().urls()
    filename = urls[0].toLocalFile()
    if os.path.isdir(filename):
        self.appendFolder(filename)
    else:
        self.appendFile(filename)
    event.acceptProposedAction()

Поскольку мы получаем путь к файлу, создайте новый элемент виджета списка и добавьте его в виджет списка:

item = QListWidgetItem()
item.setText(filename)
self.ui.listWidget.addItem(item)

Чтобы отобразить изображение в метке QT, нам нужно преобразовать MAT в qimage:

def showImage(self, filename):
    frame = cv2.imread(filename)
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    image = QImage(frame, frame.shape[1], frame.shape[0], frame.strides[0], QImage.Format_RGB888)
    pixmap = QPixmap.fromImage(image)
    self._pixmap = self.resizeImage(pixmap)
    self.ui.label.setPixmap(self._pixmap)
    return frame

Шаг 3: Получить значение слайдера и преобразовать изображение в WebP

Поскольку последний OpenCV поддерживает WebP, удобно конвертировать изображение в WebP, используя cv2.imwrite () :

quality = int(self.ui.horizontalSlider.value())
frame = cv2.imread(filename)
webp_file = filename.split('.')[0] + '.webp'
cv2.imwrite(webp_file, frame, [cv2.IMWRITE_WEBP_QUALITY, quality])

Учитывая производительность работы нескольких изображений, мы перемещаем код преобразования WebP в рабочей нити. Кроме того, отображение панели выполнения делает приложение более отзывчивым.

class Worker(QObject):
    finished = Signal()
    progress = Signal(object)

    def __init__(self, files, quality):
        super(Worker, self).__init__()
        self.files = files
        self.total = len(files)
        self.isRunning = True
        self.quality = quality

    def run(self):
        count = 0
        keys = list(self.files.keys())
        while self.isRunning and len(self.files) > 0:
            filename = keys[count]
            count += 1
            print(filename)
            frame = cv2.imread(filename)
            webp_file = filename.split('.')[0] + '.webp'
            cv2.imwrite(webp_file, frame, [cv2.IMWRITE_WEBP_QUALITY, self.quality])
            self.progress.emit((webp_file, count, self.total))
            self.files.pop(filename)

        self.finished.emit()

def reportProgress(self, data):
    filename, completed, total = data
    self.addImage(filename)
    if not self.isProcessing:
        return

    progress = completed
    self.progress_dialog.setLabelText(str(completed) +"/"+ str(total))
    self.progress_dialog.setValue(progress)
    if completed == total:
        self.onProgressDialogCanceled()
        self.showMessageBox('WebP Conversion', "Done!")

def onProgressDialogCanceled(self):
    self.isProcessing = False
    self.worker.isRunning = False
    self.progress_dialog.cancel()

def runLongTask(self):
    if (len(self._all_images) == 0):
        return

    self.isProcessing = True
    self.progress_dialog = QProgressDialog('Progress', 'Cancel', 0, len(self._all_images), self)
    self.progress_dialog.setLabelText('Progress')
    self.progress_dialog.setCancelButtonText('Cancel')
    self.progress_dialog.setRange(0, len(self._all_images))
    self.progress_dialog.setValue(0)
    self.progress_dialog.setMinimumDuration(0)
    self.progress_dialog.show()
    self.progress_dialog.canceled.connect(self.onProgressDialogCanceled)

    self.thread = QThread()
    self.worker = Worker(self._all_images, int(self.ui.label_slider.text()))
    self.worker.moveToThread(self.thread)
    self.thread.started.connect(self.worker.run)
    self.worker.finished.connect(self.thread.quit)
    self.worker.finished.connect(self.worker.deleteLater)
    self.thread.finished.connect(self.thread.deleteLater)
    self.worker.progress.connect(self.reportProgress)
    self.thread.start()

Шаг 4: Запустите приложение для преобразования изображений в WebP

python main.py

Исходный код

https://github.com/yushulx/webp-image-conversion

Оригинал: “https://dev.to/yushulx/how-to-build-a-simple-webp-conversion-tool-with-python-qt-and-opencv-3i7c”