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> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>741</width> <width>650</width>
<height>372</height> <height>400</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -17,13 +17,46 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
<string>ocr.queue.title</string> <string>queue.title</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <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> <item>
<widget class="QPushButton" name="ocr_addImageButton"> <widget class="QPushButton" name="ocr_addImageButton">
<property name="text"> <property name="text">
<string>ocr.queue.addImageButton</string> <string>queue.addImageButton</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -33,7 +66,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>ocr.queue.removeSelected</string> <string>queue.removeSelected</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -43,7 +76,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>ocr.queue.removeAll</string> <string>queue.removeAll</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -63,7 +96,7 @@
<item> <item>
<widget class="QPushButton" name="ocr_startButton"> <widget class="QPushButton" name="ocr_startButton">
<property name="text"> <property name="text">
<string>ocr.queue.startOcrButton</string> <string>queue.startOcrButton</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -115,7 +148,7 @@
<item> <item>
<widget class="QGroupBox" name="groupBox_5"> <widget class="QGroupBox" name="groupBox_5">
<property name="title"> <property name="title">
<string>ocr.results</string> <string>results</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="verticalLayout_4">
<item> <item>
@ -124,14 +157,14 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>ocr.results.acceptSelectedButton</string> <string>results.acceptSelectedButton</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="ocr_acceptAllButton"> <widget class="QPushButton" name="ocr_acceptAllButton">
<property name="text"> <property name="text">
<string>ocr.results.acceptAllButton</string> <string>results.acceptAllButton</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -151,7 +184,7 @@
<item> <item>
<widget class="QCheckBox" name="ocr_ignoreValidateCheckBox"> <widget class="QCheckBox" name="ocr_ignoreValidateCheckBox">
<property name="text"> <property name="text">
<string>ocr.results.ignoreValidate</string> <string>results.ignoreValidate</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -3,7 +3,7 @@
################################################################################ ################################################################################
## Form generated from reading UI file 'ocrQueue.ui' ## 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! ## 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) QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QCheckBox, QGroupBox, from PySide6.QtWidgets import (QAbstractItemView, QApplication, QCheckBox, QGroupBox,
QHBoxLayout, QHeaderView, QProgressBar, QPushButton, QHBoxLayout, QHeaderView, QProgressBar, QPushButton,
QSizePolicy, QSpacerItem, QTableView, QVBoxLayout, QRadioButton, QSizePolicy, QSpacerItem, QTableView,
QWidget) QVBoxLayout, QWidget)
class Ui_OcrQueue(object): class Ui_OcrQueue(object):
def setupUi(self, OcrQueue): def setupUi(self, OcrQueue):
if not OcrQueue.objectName(): if not OcrQueue.objectName():
OcrQueue.setObjectName(u"OcrQueue") OcrQueue.setObjectName(u"OcrQueue")
OcrQueue.resize(741, 372) OcrQueue.resize(650, 400)
OcrQueue.setWindowTitle(u"OcrQueue") OcrQueue.setWindowTitle(u"OcrQueue")
self.horizontalLayout_2 = QHBoxLayout(OcrQueue) self.horizontalLayout_2 = QHBoxLayout(OcrQueue)
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
@ -32,6 +32,29 @@ class Ui_OcrQueue(object):
self.groupBox_3.setObjectName(u"groupBox_3") self.groupBox_3.setObjectName(u"groupBox_3")
self.verticalLayout_2 = QVBoxLayout(self.groupBox_3) self.verticalLayout_2 = QVBoxLayout(self.groupBox_3)
self.verticalLayout_2.setObjectName(u"verticalLayout_2") 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 = QPushButton(self.groupBox_3)
self.ocr_addImageButton.setObjectName(u"ocr_addImageButton") self.ocr_addImageButton.setObjectName(u"ocr_addImageButton")
@ -120,15 +143,19 @@ class Ui_OcrQueue(object):
# setupUi # setupUi
def retranslateUi(self, OcrQueue): def retranslateUi(self, OcrQueue):
self.groupBox_3.setTitle(QCoreApplication.translate("OcrQueue", u"ocr.queue.title", None)) self.groupBox_3.setTitle(QCoreApplication.translate("OcrQueue", u"queue.title", None))
self.ocr_addImageButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.addImageButton", None)) self.groupBox.setTitle(QCoreApplication.translate("OcrQueue", u"iccOptionsGroupBox", None))
self.ocr_removeSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.removeSelected", None)) self.iccIgnoreRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.ignore", None))
self.ocr_removeAllButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.removeAll", None)) self.iccUsePILRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.usePIL", None))
self.ocr_startButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.queue.startOcrButton", None)) self.iccTryFixRadioButton.setText(QCoreApplication.translate("OcrQueue", u"icc.tryFix", None))
self.groupBox_5.setTitle(QCoreApplication.translate("OcrQueue", u"ocr.results", None)) self.ocr_addImageButton.setText(QCoreApplication.translate("OcrQueue", u"queue.addImageButton", None))
self.ocr_acceptSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.acceptSelectedButton", None)) self.ocr_removeSelectedButton.setText(QCoreApplication.translate("OcrQueue", u"queue.removeSelected", None))
self.ocr_acceptAllButton.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.acceptAllButton", None)) self.ocr_removeAllButton.setText(QCoreApplication.translate("OcrQueue", u"queue.removeAll", None))
self.ocr_ignoreValidateCheckBox.setText(QCoreApplication.translate("OcrQueue", u"ocr.results.ignoreValidate", 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 pass
# retranslateUi # retranslateUi

View File

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

View File

@ -2,7 +2,7 @@ from typing import Optional
from PySide6.QtCore import Qt, QTimer, Slot from PySide6.QtCore import Qt, QTimer, Slot
from PySide6.QtGui import QColor, QPalette 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.designer.components.ocrQueue_ui import Ui_OcrQueue
from ui.extends.components.ocrQueue import ( from ui.extends.components.ocrQueue import (
@ -36,6 +36,13 @@ class OcrQueue(Ui_OcrQueue, QWidget):
tableViewPalette.setColor(QPalette.ColorRole.Highlight, highlightColor) tableViewPalette.setColor(QPalette.ColorRole.Highlight, highlightColor)
self.tableView.setPalette(tableViewPalette) 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): def model(self):
return self.__model return self.__model
@ -77,6 +84,10 @@ class OcrQueue(Ui_OcrQueue, QWidget):
self.ocr_acceptAllButton.setEnabled(__bool) self.ocr_acceptAllButton.setEnabled(__bool)
self.ocr_ignoreValidateCheckBox.setEnabled(__bool) self.ocr_ignoreValidateCheckBox.setEnabled(__bool)
def updateIccOption(self):
if self.model():
self.model().iccOption = self.iccOptionButtonGroup.checkedId()
def resizeTableView(self): def resizeTableView(self):
self.tableView.resizeRowsToContents() self.tableView.resizeRowsToContents()
self.tableView.resizeColumnsToContents() self.tableView.resizeColumnsToContents()

View File

@ -215,47 +215,67 @@
<name>OcrQueue</name> <name>OcrQueue</name>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="20"/> <location filename="../../designer/components/ocrQueue.ui" line="20"/>
<source>ocr.queue.title</source> <source>queue.title</source>
<translation>Queue</translation> <translation>Queue</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="26"/> <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> <translation>Add Image</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="36"/> <location filename="../../designer/components/ocrQueue.ui" line="69"/>
<source>ocr.queue.removeSelected</source> <source>queue.removeSelected</source>
<translation>Remove Selected</translation> <translation>Remove Selected</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="46"/> <location filename="../../designer/components/ocrQueue.ui" line="79"/>
<source>ocr.queue.removeAll</source> <source>queue.removeAll</source>
<translation>Remove All</translation> <translation>Remove All</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="66"/> <location filename="../../designer/components/ocrQueue.ui" line="99"/>
<source>ocr.queue.startOcrButton</source> <source>queue.startOcrButton</source>
<translation>Start OCR</translation> <translation>Start OCR</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="118"/> <location filename="../../designer/components/ocrQueue.ui" line="151"/>
<source>ocr.results</source> <source>results</source>
<translation>Results</translation> <translation>Results</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="127"/> <location filename="../../designer/components/ocrQueue.ui" line="160"/>
<source>ocr.results.acceptSelectedButton</source> <source>results.acceptSelectedButton</source>
<translation>Accept Selected</translation> <translation>Accept Selected</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="134"/> <location filename="../../designer/components/ocrQueue.ui" line="167"/>
<source>ocr.results.acceptAllButton</source> <source>results.acceptAllButton</source>
<translation>Accept All</translation> <translation>Accept All</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="154"/> <location filename="../../designer/components/ocrQueue.ui" line="187"/>
<source>ocr.results.ignoreValidate</source> <source>results.ignoreValidate</source>
<translation>Ignore <translation>Ignore
validation</translation> validation</translation>
</message> </message>
@ -263,22 +283,22 @@ validation</translation>
<context> <context>
<name>OcrTableModel</name> <name>OcrTableModel</name>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="313"/> <location filename="../../extends/components/ocrQueue.py" line="341"/>
<source>horizontalHeader.title.select</source> <source>horizontalHeader.title.select</source>
<translation>Select</translation> <translation>Select</translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="314"/> <location filename="../../extends/components/ocrQueue.py" line="342"/>
<source>horizontalHeader.title.imagePreview</source> <source>horizontalHeader.title.imagePreview</source>
<translation>Image Preview</translation> <translation>Image Preview</translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="315"/> <location filename="../../extends/components/ocrQueue.py" line="343"/>
<source>horizontalHeader.title.chart</source> <source>horizontalHeader.title.chart</source>
<translation>Chart</translation> <translation>Chart</translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="316"/> <location filename="../../extends/components/ocrQueue.py" line="344"/>
<source>horizontalHeader.title.score</source> <source>horizontalHeader.title.score</source>
<translation>Score</translation> <translation>Score</translation>
</message> </message>

View File

@ -215,69 +215,89 @@
<name>OcrQueue</name> <name>OcrQueue</name>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="20"/> <location filename="../../designer/components/ocrQueue.ui" line="20"/>
<source>ocr.queue.title</source> <source>queue.title</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="26"/> <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> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="36"/> <location filename="../../designer/components/ocrQueue.ui" line="69"/>
<source>ocr.queue.removeSelected</source> <source>queue.removeSelected</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="46"/> <location filename="../../designer/components/ocrQueue.ui" line="79"/>
<source>ocr.queue.removeAll</source> <source>queue.removeAll</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="66"/> <location filename="../../designer/components/ocrQueue.ui" line="99"/>
<source>ocr.queue.startOcrButton</source> <source>queue.startOcrButton</source>
<translation> OCR</translation> <translation> OCR</translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="118"/> <location filename="../../designer/components/ocrQueue.ui" line="151"/>
<source>ocr.results</source> <source>results</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="127"/> <location filename="../../designer/components/ocrQueue.ui" line="160"/>
<source>ocr.results.acceptSelectedButton</source> <source>results.acceptSelectedButton</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="134"/> <location filename="../../designer/components/ocrQueue.ui" line="167"/>
<source>ocr.results.acceptAllButton</source> <source>results.acceptAllButton</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../designer/components/ocrQueue.ui" line="154"/> <location filename="../../designer/components/ocrQueue.ui" line="187"/>
<source>ocr.results.ignoreValidate</source> <source>results.ignoreValidate</source>
<translation></translation> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
<name>OcrTableModel</name> <name>OcrTableModel</name>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="313"/> <location filename="../../extends/components/ocrQueue.py" line="341"/>
<source>horizontalHeader.title.select</source> <source>horizontalHeader.title.select</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="314"/> <location filename="../../extends/components/ocrQueue.py" line="342"/>
<source>horizontalHeader.title.imagePreview</source> <source>horizontalHeader.title.imagePreview</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="315"/> <location filename="../../extends/components/ocrQueue.py" line="343"/>
<source>horizontalHeader.title.chart</source> <source>horizontalHeader.title.chart</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../../extends/components/ocrQueue.py" line="316"/> <location filename="../../extends/components/ocrQueue.py" line="344"/>
<source>horizontalHeader.title.score</source> <source>horizontalHeader.title.score</source>
<translation></translation> <translation></translation>
</message> </message>