fix: try fix icc profile issues by using PIL to load image

- use PIL to ignore Qt warning: `qt.gui.icc: fromIccProfile: Failed to parse description`
This commit is contained in:
283375 2023-09-06 21:47:42 +08:00
parent 3f42be3212
commit 8c5d7ae414
6 changed files with 206 additions and 67 deletions

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<height>372</height>
<width>650</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
@ -17,13 +17,46 @@
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>ocr.queue.title</string>
<string>queue.title</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>iccOptionsGroupBox</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="iccIgnoreRadioButton">
<property name="text">
<string>icc.ignore</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="iccUsePILRadioButton">
<property name="text">
<string>icc.usePIL</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="iccTryFixRadioButton">
<property name="text">
<string>icc.tryFix</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QPushButton" name="ocr_addImageButton">
<property name="text">
<string>ocr.queue.addImageButton</string>
<string>queue.addImageButton</string>
</property>
</widget>
</item>
@ -33,7 +66,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>ocr.queue.removeSelected</string>
<string>queue.removeSelected</string>
</property>
</widget>
</item>
@ -43,7 +76,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>ocr.queue.removeAll</string>
<string>queue.removeAll</string>
</property>
</widget>
</item>
@ -63,7 +96,7 @@
<item>
<widget class="QPushButton" name="ocr_startButton">
<property name="text">
<string>ocr.queue.startOcrButton</string>
<string>queue.startOcrButton</string>
</property>
</widget>
</item>
@ -115,7 +148,7 @@
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>ocr.results</string>
<string>results</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
@ -124,14 +157,14 @@
<bool>true</bool>
</property>
<property name="text">
<string>ocr.results.acceptSelectedButton</string>
<string>results.acceptSelectedButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ocr_acceptAllButton">
<property name="text">
<string>ocr.results.acceptAllButton</string>
<string>results.acceptAllButton</string>
</property>
</widget>
</item>
@ -151,7 +184,7 @@
<item>
<widget class="QCheckBox" name="ocr_ignoreValidateCheckBox">
<property name="text">
<string>ocr.results.ignoreValidate</string>
<string>results.ignoreValidate</string>
</property>
</widget>
</item>

View File

@ -3,7 +3,7 @@
################################################################################
## Form generated from reading UI file 'ocrQueue.ui'
##
## Created by: Qt User Interface Compiler version 6.5.1
## Created by: Qt User Interface Compiler version 6.5.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
@ -17,14 +17,14 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QCheckBox, QGroupBox,
QHBoxLayout, QHeaderView, QProgressBar, QPushButton,
QSizePolicy, QSpacerItem, QTableView, QVBoxLayout,
QWidget)
QRadioButton, QSizePolicy, QSpacerItem, QTableView,
QVBoxLayout, QWidget)
class Ui_OcrQueue(object):
def setupUi(self, OcrQueue):
if not OcrQueue.objectName():
OcrQueue.setObjectName(u"OcrQueue")
OcrQueue.resize(741, 372)
OcrQueue.resize(650, 400)
OcrQueue.setWindowTitle(u"OcrQueue")
self.horizontalLayout_2 = QHBoxLayout(OcrQueue)
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
@ -32,6 +32,29 @@ class Ui_OcrQueue(object):
self.groupBox_3.setObjectName(u"groupBox_3")
self.verticalLayout_2 = QVBoxLayout(self.groupBox_3)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.groupBox = QGroupBox(self.groupBox_3)
self.groupBox.setObjectName(u"groupBox")
self.verticalLayout = QVBoxLayout(self.groupBox)
self.verticalLayout.setObjectName(u"verticalLayout")
self.iccIgnoreRadioButton = QRadioButton(self.groupBox)
self.iccIgnoreRadioButton.setObjectName(u"iccIgnoreRadioButton")
self.verticalLayout.addWidget(self.iccIgnoreRadioButton)
self.iccUsePILRadioButton = QRadioButton(self.groupBox)
self.iccUsePILRadioButton.setObjectName(u"iccUsePILRadioButton")
self.iccUsePILRadioButton.setChecked(True)
self.verticalLayout.addWidget(self.iccUsePILRadioButton)
self.iccTryFixRadioButton = QRadioButton(self.groupBox)
self.iccTryFixRadioButton.setObjectName(u"iccTryFixRadioButton")
self.verticalLayout.addWidget(self.iccTryFixRadioButton)
self.verticalLayout_2.addWidget(self.groupBox)
self.ocr_addImageButton = QPushButton(self.groupBox_3)
self.ocr_addImageButton.setObjectName(u"ocr_addImageButton")
@ -120,15 +143,19 @@ class Ui_OcrQueue(object):
# setupUi
def retranslateUi(self, OcrQueue):
self.groupBox_3.setTitle(QCoreApplication.translate("OcrQueue", u"ocr.queue.title", None))
self.ocr_addImageButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.addImageButton", None))
self.ocr_removeSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.removeSelected", None))
self.ocr_removeAllButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.removeAll", None))
self.ocr_startButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.startOcrButton", None))
self.groupBox_5.setTitle(QCoreApplication.translate("OcrQueue", u"ocr.results", None))
self.ocr_acceptSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.acceptSelectedButton", None))
self.ocr_acceptAllButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.acceptAllButton", None))
self.ocr_ignoreValidateCheckBox.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.ignoreValidate", None))
self.groupBox_3.setTitle(QCoreApplication.translate("OcrQueue", u"queue.title", None))
self.groupBox.setTitle(QCoreApplication.translate("OcrQueue", u"iccOptionsGroupBox", None))
self.iccIgnoreRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.ignore", None))
self.iccUsePILRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.usePIL", None))
self.iccTryFixRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.tryFix", None))
self.ocr_addImageButton.setText(QCoreApplication.translate("OcrQueue", u"queue.addImageButton", None))
self.ocr_removeSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"queue.removeSelected", None))
self.ocr_removeAllButton.setText(QCoreApplication.translate("OcrQueue", u"queue.removeAll", None))
self.ocr_startButton.setText(QCoreApplication.translate("OcrQueue", u"queue.startOcrButton", None))
self.groupBox_5.setTitle(QCoreApplication.translate("OcrQueue", u"results", None))
self.ocr_acceptSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"results.acceptSelectedButton", None))
self.ocr_acceptAllButton.setText(QCoreApplication.translate("OcrQueue", u"results.acceptAllButton", None))
self.ocr_ignoreValidateCheckBox.setText(QCoreApplication.translate("OcrQueue", u"results.ignoreValidate", None))
pass
# retranslateUi

View File

@ -1,4 +1,5 @@
import logging
from enum import IntEnum
from typing import Any, Callable, Optional, overload
from arcaea_offline.calculate import calculate_score_range
@ -6,6 +7,9 @@ from arcaea_offline.database import Database
from arcaea_offline.models import Chart, Score
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
from arcaea_offline_ocr.device.shared import DeviceOcrResult
from arcaea_offline_ocr.utils import convert_to_srgb
from PIL import Image
from PIL.ImageQt import ImageQt
from PySide6.QtCore import (
QAbstractListModel,
QAbstractTableModel,
@ -41,6 +45,12 @@ class OcrRunnable(QRunnable):
self.signals = OcrRunnableSignals()
class IccOption(IntEnum):
Ignore = 0
UsePIL = 1
TryFix = 2
class OcrQueueModel(QAbstractListModel):
ImagePathRole = Qt.ItemDataRole.UserRole + 1
ImageQImageRole = Qt.ItemDataRole.UserRole + 2
@ -64,6 +74,7 @@ class OcrQueueModel(QAbstractListModel):
super().__init__(parent)
self.__db = Database()
self.__items: list[dict[int, Any]] = []
self.__iccOption = IccOption.UsePIL
self.__taskFinishedNum = 0
@ -133,6 +144,14 @@ class OcrQueueModel(QAbstractListModel):
)
return False
@property
def iccOption(self):
return self.__iccOption
@iccOption.setter
def iccOption(self, opt: IccOption):
self.__iccOption = opt
@overload
def addItem(
self,
@ -162,8 +181,17 @@ class OcrQueueModel(QAbstractListModel):
logger.warning(f"Attempting to add an invalid file {image}")
return
imagePath = image
qImage = QImage(image)
qPixmap = QPixmap(image)
if self.iccOption == IccOption.TryFix:
img = Image.open(image)
img = convert_to_srgb(img)
qImage = ImageQt(img)
elif self.iccOption == IccOption.UsePIL:
img = Image.open(image)
qImage = ImageQt(img)
else:
qImage = QImage(image)
qPixmap = QPixmap(qImage)
elif isinstance(image, QImage):
imagePath = None
qImage = image.copy()

View File

@ -2,7 +2,7 @@ from typing import Optional
from PySide6.QtCore import Qt, QTimer, Slot
from PySide6.QtGui import QColor, QPalette
from PySide6.QtWidgets import QWidget
from PySide6.QtWidgets import QButtonGroup, QWidget
from ui.designer.components.ocrQueue_ui import Ui_OcrQueue
from ui.extends.components.ocrQueue import (
@ -36,6 +36,13 @@ class OcrQueue(Ui_OcrQueue, QWidget):
tableViewPalette.setColor(QPalette.ColorRole.Highlight, highlightColor)
self.tableView.setPalette(tableViewPalette)
self.iccOptionButtonGroup = QButtonGroup(self)
self.iccOptionButtonGroup.buttonToggled.connect(self.updateIccOption)
self.iccOptionButtonGroup.addButton(self.iccIgnoreRadioButton, 0)
self.iccOptionButtonGroup.addButton(self.iccUsePILRadioButton, 1)
self.iccOptionButtonGroup.addButton(self.iccTryFixRadioButton, 2)
self.updateIccOption()
def model(self):
return self.__model
@ -77,6 +84,10 @@ class OcrQueue(Ui_OcrQueue, QWidget):
self.ocr_acceptAllButton.setEnabled(__bool)
self.ocr_ignoreValidateCheckBox.setEnabled(__bool)
def updateIccOption(self):
if self.model():
self.model().iccOption = self.iccOptionButtonGroup.checkedId()
def resizeTableView(self):
self.tableView.resizeRowsToContents()
self.tableView.resizeColumnsToContents()

View File

@ -215,47 +215,67 @@
<name>OcrQueue</name>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="20"/>
<source>ocr.queue.title</source>
<source>queue.title</source>
<translation>Queue</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="26"/>
<source>ocr.queue.addImageButton</source>
<source>iccOptionsGroupBox</source>
<translation>ICC Profile Options</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="32"/>
<source>icc.ignore</source>
<translation>Ignore</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="39"/>
<source>icc.usePIL</source>
<translation>Use PIL</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="49"/>
<source>icc.tryFix</source>
<translation>Try fix</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="59"/>
<source>queue.addImageButton</source>
<translation>Add Image</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="36"/>
<source>ocr.queue.removeSelected</source>
<location filename="../../designer/components/ocrQueue.ui" line="69"/>
<source>queue.removeSelected</source>
<translation>Remove Selected</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="46"/>
<source>ocr.queue.removeAll</source>
<location filename="../../designer/components/ocrQueue.ui" line="79"/>
<source>queue.removeAll</source>
<translation>Remove All</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="66"/>
<source>ocr.queue.startOcrButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="99"/>
<source>queue.startOcrButton</source>
<translation>Start OCR</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="118"/>
<source>ocr.results</source>
<location filename="../../designer/components/ocrQueue.ui" line="151"/>
<source>results</source>
<translation>Results</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="127"/>
<source>ocr.results.acceptSelectedButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="160"/>
<source>results.acceptSelectedButton</source>
<translation>Accept Selected</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="134"/>
<source>ocr.results.acceptAllButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="167"/>
<source>results.acceptAllButton</source>
<translation>Accept All</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="154"/>
<source>ocr.results.ignoreValidate</source>
<location filename="../../designer/components/ocrQueue.ui" line="187"/>
<source>results.ignoreValidate</source>
<translation>Ignore
validation</translation>
</message>
@ -263,22 +283,22 @@ validation</translation>
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="313"/>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<source>horizontalHeader.title.select</source>
<translation>Select</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="314"/>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<source>horizontalHeader.title.imagePreview</source>
<translation>Image Preview</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="315"/>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<source>horizontalHeader.title.chart</source>
<translation>Chart</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="316"/>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<source>horizontalHeader.title.score</source>
<translation>Score</translation>
</message>

View File

@ -215,69 +215,89 @@
<name>OcrQueue</name>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="20"/>
<source>ocr.queue.title</source>
<source>queue.title</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="26"/>
<source>ocr.queue.addImageButton</source>
<source>iccOptionsGroupBox</source>
<translation>ICC </translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="32"/>
<source>icc.ignore</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="39"/>
<source>icc.usePIL</source>
<translation>使 PIL </translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="49"/>
<source>icc.tryFix</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="59"/>
<source>queue.addImageButton</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="36"/>
<source>ocr.queue.removeSelected</source>
<location filename="../../designer/components/ocrQueue.ui" line="69"/>
<source>queue.removeSelected</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="46"/>
<source>ocr.queue.removeAll</source>
<location filename="../../designer/components/ocrQueue.ui" line="79"/>
<source>queue.removeAll</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="66"/>
<source>ocr.queue.startOcrButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="99"/>
<source>queue.startOcrButton</source>
<translation> OCR</translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="118"/>
<source>ocr.results</source>
<location filename="../../designer/components/ocrQueue.ui" line="151"/>
<source>results</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="127"/>
<source>ocr.results.acceptSelectedButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="160"/>
<source>results.acceptSelectedButton</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="134"/>
<source>ocr.results.acceptAllButton</source>
<location filename="../../designer/components/ocrQueue.ui" line="167"/>
<source>results.acceptAllButton</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/ocrQueue.ui" line="154"/>
<source>ocr.results.ignoreValidate</source>
<location filename="../../designer/components/ocrQueue.ui" line="187"/>
<source>results.ignoreValidate</source>
<translation></translation>
</message>
</context>
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="313"/>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<source>horizontalHeader.title.select</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="314"/>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<source>horizontalHeader.title.imagePreview</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="315"/>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<source>horizontalHeader.title.chart</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="316"/>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<source>horizontalHeader.title.score</source>
<translation></translation>
</message>