«WebP – это формат изображения, использующий как сжатие с потерями, так и без потерь, и поддерживает анимацию и прозрачность альфа. Разработанный Google, он предназначен для создания файлов, которые меньше для того же качества, или более высокого качества для того же размера, чем форматы IPEG, PNG и GIF, – Wikipedia . Скорость является одним из ключевых факторов оптимизации SEO. Разработчики имеют тенденцию использовать WebP для замены JPEG, PNG и GIF, чтобы сделать веб-страницы SEO дружелюбным. Эта статья демонстрирует, как построить простой инструмент преобразования WebP с Python, Qt и OpenCV.
Установка
- Python 3.x.
Opencv и Qt (pyside2 или pyside6)
Разработка инструмента преобразования 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”