mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-07-01 04:16:26 +00:00
feat: TabOcr_BuildPHashDatabase
This commit is contained in:
255
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui
Normal file
255
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui
Normal file
@ -0,0 +1,255 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>tabOcr_BuildPHashDatabase</class>
|
||||
<widget class="QWidget" name="tabOcr_BuildPHashDatabase">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>632</width>
|
||||
<height>551</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">tabOcr_BuildPHashDatabase</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>folders.title</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>folders.songDir</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="FileSelector" name="songDirSelector" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>folders.charIconDir</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="FileSelector" name="charIconDirSelector" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>options.title</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">hash_size</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="hashSizeSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>16</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string notr="true">highfreq_factor</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="highfreqFactorSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="optionsResetButton">
|
||||
<property name="text">
|
||||
<string>resetButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="format">
|
||||
<string notr="true">%v/%m - %p%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buildButton">
|
||||
<property name="text">
|
||||
<string>buildButton</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>FileSelector</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>ui.implements.components.fileSelector</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
193
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase_ui.py
Normal file
193
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase_ui.py
Normal file
@ -0,0 +1,193 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'tabOcr_BuildPHashDatabase.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.5.2
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
|
||||
QProgressBar, QPushButton, QSizePolicy, QSpacerItem,
|
||||
QSpinBox, QVBoxLayout, QWidget)
|
||||
|
||||
from ui.implements.components.fileSelector import FileSelector
|
||||
|
||||
class Ui_tabOcr_BuildPHashDatabase(object):
|
||||
def setupUi(self, tabOcr_BuildPHashDatabase):
|
||||
if not tabOcr_BuildPHashDatabase.objectName():
|
||||
tabOcr_BuildPHashDatabase.setObjectName(u"tabOcr_BuildPHashDatabase")
|
||||
tabOcr_BuildPHashDatabase.resize(632, 551)
|
||||
tabOcr_BuildPHashDatabase.setWindowTitle(u"tabOcr_BuildPHashDatabase")
|
||||
self.verticalLayout_3 = QVBoxLayout(tabOcr_BuildPHashDatabase)
|
||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
|
||||
self.verticalLayout_3.addItem(self.verticalSpacer)
|
||||
|
||||
self.groupBox = QGroupBox(tabOcr_BuildPHashDatabase)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.verticalLayout = QVBoxLayout(self.groupBox)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.label = QLabel(self.groupBox)
|
||||
self.label.setObjectName(u"label")
|
||||
|
||||
self.horizontalLayout.addWidget(self.label)
|
||||
|
||||
self.songDirSelector = FileSelector(self.groupBox)
|
||||
self.songDirSelector.setObjectName(u"songDirSelector")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.songDirSelector.sizePolicy().hasHeightForWidth())
|
||||
self.songDirSelector.setSizePolicy(sizePolicy)
|
||||
|
||||
self.horizontalLayout.addWidget(self.songDirSelector)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||
self.label_2 = QLabel(self.groupBox)
|
||||
self.label_2.setObjectName(u"label_2")
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.label_2)
|
||||
|
||||
self.charIconDirSelector = FileSelector(self.groupBox)
|
||||
self.charIconDirSelector.setObjectName(u"charIconDirSelector")
|
||||
sizePolicy.setHeightForWidth(self.charIconDirSelector.sizePolicy().hasHeightForWidth())
|
||||
self.charIconDirSelector.setSizePolicy(sizePolicy)
|
||||
|
||||
self.horizontalLayout_2.addWidget(self.charIconDirSelector)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
|
||||
|
||||
self.verticalLayout_3.addWidget(self.groupBox)
|
||||
|
||||
self.groupBox_2 = QGroupBox(tabOcr_BuildPHashDatabase)
|
||||
self.groupBox_2.setObjectName(u"groupBox_2")
|
||||
self.horizontalLayout_3 = QHBoxLayout(self.groupBox_2)
|
||||
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||
self.verticalLayout_2 = QVBoxLayout()
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.horizontalLayout_6 = QHBoxLayout()
|
||||
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||
self.label_3 = QLabel(self.groupBox_2)
|
||||
self.label_3.setObjectName(u"label_3")
|
||||
self.label_3.setText(u"hash_size")
|
||||
self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.label_3)
|
||||
|
||||
self.hashSizeSpinBox = QSpinBox(self.groupBox_2)
|
||||
self.hashSizeSpinBox.setObjectName(u"hashSizeSpinBox")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.hashSizeSpinBox.sizePolicy().hasHeightForWidth())
|
||||
self.hashSizeSpinBox.setSizePolicy(sizePolicy1)
|
||||
self.hashSizeSpinBox.setMinimum(2)
|
||||
self.hashSizeSpinBox.setMaximum(64)
|
||||
self.hashSizeSpinBox.setValue(16)
|
||||
|
||||
self.horizontalLayout_6.addWidget(self.hashSizeSpinBox)
|
||||
|
||||
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_6)
|
||||
|
||||
self.horizontalLayout_7 = QHBoxLayout()
|
||||
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
||||
self.label_4 = QLabel(self.groupBox_2)
|
||||
self.label_4.setObjectName(u"label_4")
|
||||
self.label_4.setText(u"highfreq_factor")
|
||||
self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.label_4)
|
||||
|
||||
self.highfreqFactorSpinBox = QSpinBox(self.groupBox_2)
|
||||
self.highfreqFactorSpinBox.setObjectName(u"highfreqFactorSpinBox")
|
||||
sizePolicy1.setHeightForWidth(self.highfreqFactorSpinBox.sizePolicy().hasHeightForWidth())
|
||||
self.highfreqFactorSpinBox.setSizePolicy(sizePolicy1)
|
||||
self.highfreqFactorSpinBox.setMaximum(32)
|
||||
self.highfreqFactorSpinBox.setValue(4)
|
||||
|
||||
self.horizontalLayout_7.addWidget(self.highfreqFactorSpinBox)
|
||||
|
||||
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_7)
|
||||
|
||||
|
||||
self.horizontalLayout_3.addLayout(self.verticalLayout_2)
|
||||
|
||||
self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
|
||||
self.horizontalLayout_3.addItem(self.horizontalSpacer_3)
|
||||
|
||||
self.optionsResetButton = QPushButton(self.groupBox_2)
|
||||
self.optionsResetButton.setObjectName(u"optionsResetButton")
|
||||
|
||||
self.horizontalLayout_3.addWidget(self.optionsResetButton)
|
||||
|
||||
|
||||
self.verticalLayout_3.addWidget(self.groupBox_2)
|
||||
|
||||
self.progressBar = QProgressBar(tabOcr_BuildPHashDatabase)
|
||||
self.progressBar.setObjectName(u"progressBar")
|
||||
self.progressBar.setMaximum(0)
|
||||
self.progressBar.setValue(0)
|
||||
self.progressBar.setAlignment(Qt.AlignCenter)
|
||||
self.progressBar.setFormat(u"%v/%m - %p%")
|
||||
|
||||
self.verticalLayout_3.addWidget(self.progressBar)
|
||||
|
||||
self.horizontalLayout_5 = QHBoxLayout()
|
||||
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
||||
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
|
||||
self.horizontalLayout_5.addItem(self.horizontalSpacer)
|
||||
|
||||
self.buildButton = QPushButton(tabOcr_BuildPHashDatabase)
|
||||
self.buildButton.setObjectName(u"buildButton")
|
||||
|
||||
self.horizontalLayout_5.addWidget(self.buildButton)
|
||||
|
||||
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
|
||||
self.horizontalLayout_5.addItem(self.horizontalSpacer_2)
|
||||
|
||||
|
||||
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
|
||||
|
||||
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
|
||||
self.verticalLayout_3.addItem(self.verticalSpacer_2)
|
||||
|
||||
|
||||
self.retranslateUi(tabOcr_BuildPHashDatabase)
|
||||
|
||||
QMetaObject.connectSlotsByName(tabOcr_BuildPHashDatabase)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, tabOcr_BuildPHashDatabase):
|
||||
self.groupBox.setTitle(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.title", None))
|
||||
self.label.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.songDir", None))
|
||||
self.label_2.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.charIconDir", None))
|
||||
self.groupBox_2.setTitle(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"options.title", None))
|
||||
self.optionsResetButton.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"resetButton", None))
|
||||
self.buildButton.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"buildButton", None))
|
||||
pass
|
||||
# retranslateUi
|
||||
|
@ -29,6 +29,11 @@
|
||||
<string>tab.b30</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="TabOcr_BuildPHashDatabase" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>tab.buildPHashDatabase</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -46,6 +51,12 @@
|
||||
<header>ui.implements.tabs.tabOcr.tabOcr_B30</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TabOcr_BuildPHashDatabase</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>ui.implements.tabs.tabOcr.tabOcr_BuildPHashDatabase</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
@ -3,7 +3,7 @@
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'tabOcrEntry.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!
|
||||
################################################################################
|
||||
@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou
|
||||
QWidget)
|
||||
|
||||
from ui.implements.tabs.tabOcr.tabOcr_B30 import TabOcr_B30
|
||||
from ui.implements.tabs.tabOcr.tabOcr_BuildPHashDatabase import TabOcr_BuildPHashDatabase
|
||||
from ui.implements.tabs.tabOcr.tabOcr_Device import TabOcr_Device
|
||||
|
||||
class Ui_TabOcrEntry(object):
|
||||
@ -37,6 +38,9 @@ class Ui_TabOcrEntry(object):
|
||||
self.tab_2 = TabOcr_B30()
|
||||
self.tab_2.setObjectName(u"tab_2")
|
||||
self.tabWidget.addTab(self.tab_2, "")
|
||||
self.tab_3 = TabOcr_BuildPHashDatabase()
|
||||
self.tab_3.setObjectName(u"tab_3")
|
||||
self.tabWidget.addTab(self.tab_3, "")
|
||||
|
||||
self.verticalLayout.addWidget(self.tabWidget)
|
||||
|
||||
@ -52,6 +56,7 @@ class Ui_TabOcrEntry(object):
|
||||
def retranslateUi(self, TabOcrEntry):
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabOcrEntry", u"tab.device", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabOcrEntry", u"tab.b30", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabOcrEntry", u"tab.buildPHashDatabase", None))
|
||||
pass
|
||||
# retranslateUi
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
from .build_phash import build_image_phash_database
|
||||
|
||||
try:
|
||||
import json
|
||||
|
61
ui/extends/ocr/build_phash.py
Normal file
61
ui/extends/ocr/build_phash.py
Normal file
@ -0,0 +1,61 @@
|
||||
import sqlite3
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Optional
|
||||
|
||||
import cv2
|
||||
from arcaea_offline_ocr.phash_db import phash_opencv
|
||||
|
||||
|
||||
def build_image_phash_database(
|
||||
images: list[Path],
|
||||
labels: list[str],
|
||||
*,
|
||||
hash_size: int = 16,
|
||||
highfreq_factor: int = 4,
|
||||
progress_func: Optional[Callable[[int, int], Any]] = None,
|
||||
):
|
||||
assert len(images) == len(labels)
|
||||
|
||||
conn = sqlite3.connect(":memory:", check_same_thread=False)
|
||||
|
||||
with conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("CREATE TABLE properties (key TEXT, value TEXT)")
|
||||
cursor.executemany(
|
||||
"INSERT INTO properties VALUES (?, ?)",
|
||||
[
|
||||
("hash_size", hash_size),
|
||||
("highfreq_factor", highfreq_factor),
|
||||
],
|
||||
)
|
||||
|
||||
image_num = len(images)
|
||||
id_hashes = []
|
||||
for i, label, image_path in zip(range(image_num), labels, images):
|
||||
image_hash = phash_opencv(
|
||||
cv2.imread(str(image_path.resolve()), cv2.IMREAD_GRAYSCALE),
|
||||
hash_size=hash_size,
|
||||
highfreq_factor=highfreq_factor,
|
||||
)
|
||||
image_hash_bytes = image_hash.flatten().tobytes()
|
||||
|
||||
id_hashes.append([label, image_hash_bytes])
|
||||
if progress_func:
|
||||
progress_func(i + 1, image_num)
|
||||
|
||||
hash_length = len(id_hashes[0][1])
|
||||
cursor.execute(f"CREATE TABLE hashes (id TEXT, hash BLOB({hash_length}))")
|
||||
|
||||
cursor.executemany(
|
||||
"INSERT INTO hashes VALUES (?, ?)",
|
||||
id_hashes,
|
||||
)
|
||||
cursor.executemany(
|
||||
"INSERT INTO properties VALUES (?, ?)",
|
||||
[("built_timestamp", int(time.time()))],
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
return conn
|
138
ui/implements/tabs/tabOcr/tabOcr_BuildPHashDatabase.py
Normal file
138
ui/implements/tabs/tabOcr/tabOcr_BuildPHashDatabase.py
Normal file
@ -0,0 +1,138 @@
|
||||
import logging
|
||||
import re
|
||||
import sqlite3
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import QThread, Signal, Slot
|
||||
from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget
|
||||
|
||||
from ui.designer.tabs.tabOcr.tabOcr_BuildPHashDatabase_ui import (
|
||||
Ui_tabOcr_BuildPHashDatabase,
|
||||
)
|
||||
from ui.extends.ocr import build_image_phash_database
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BuildDatabaseThread(QThread):
|
||||
conn: sqlite3.Connection
|
||||
|
||||
progress = Signal(int, int)
|
||||
success = Signal()
|
||||
error = Signal(str)
|
||||
finished = Signal()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
images: list[Path],
|
||||
labels: list[str],
|
||||
*,
|
||||
hashSize: int | None = None,
|
||||
highfreqFactor: int | None = None,
|
||||
):
|
||||
super().__init__()
|
||||
self.images = images
|
||||
self.labels = labels
|
||||
self.hashSize = hashSize
|
||||
self.highfreqFactor = highfreqFactor
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
progressFunc = lambda i, total: self.progress.emit(i, total)
|
||||
|
||||
kwargsDict = {}
|
||||
if self.hashSize is not None:
|
||||
kwargsDict["hash_size"] = self.hashSize
|
||||
if self.highfreqFactor is not None:
|
||||
kwargsDict["highfreq_factor"] = self.highfreqFactor
|
||||
self.conn = build_image_phash_database(
|
||||
self.images, self.labels, progress_func=progressFunc, **kwargsDict
|
||||
)
|
||||
self.success.emit()
|
||||
except Exception as e:
|
||||
logger.exception("Error during pHash database build")
|
||||
self.error.emit(str(e))
|
||||
finally:
|
||||
self.finished.emit()
|
||||
|
||||
|
||||
class TabOcr_BuildPHashDatabase(Ui_tabOcr_BuildPHashDatabase, QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.songDirSelector.setMode(self.songDirSelector.getExistingDirectory)
|
||||
self.charIconDirSelector.setMode(self.charIconDirSelector.getExistingDirectory)
|
||||
|
||||
self.buildButton.clicked.connect(self.databaseBuildStart)
|
||||
|
||||
@Slot()
|
||||
def on_optionsResetButton_clicked(self):
|
||||
self.hashSizeSpinBox.setValue(16)
|
||||
self.highfreqFactorSpinBox.setValue(4)
|
||||
|
||||
def databaseFileName(self):
|
||||
return f"image-phash-{int(time.time() * 1000)}.db"
|
||||
|
||||
def databaseBuildStart(self):
|
||||
if not self.songDirSelector.selectedFiles():
|
||||
QMessageBox.critical(self, None, "Song directory not selected.")
|
||||
return
|
||||
if not self.charIconDirSelector.selectedFiles():
|
||||
QMessageBox.critical(self, None, "Char icon directory not selected.")
|
||||
return
|
||||
|
||||
songDir = self.songDirSelector.selectedFiles()[0]
|
||||
charIconDir = self.charIconDirSelector.selectedFiles()[0]
|
||||
|
||||
acceptExts = [".jpg", ".png"]
|
||||
songFilePaths = [
|
||||
p for p in Path(songDir).glob("**/*") if p.suffix in acceptExts
|
||||
]
|
||||
charIconFilePaths = [
|
||||
p for p in Path(charIconDir).glob("**/*") if p.suffix in acceptExts
|
||||
]
|
||||
songLabels = [re.sub(r"_.*$", "", p.stem) for p in songFilePaths]
|
||||
charLabels = [f"character||{p.stem}" for p in charIconFilePaths]
|
||||
|
||||
self.databaseBuildThread = BuildDatabaseThread(
|
||||
songFilePaths + charIconFilePaths, songLabels + charLabels
|
||||
)
|
||||
self.databaseBuildThread.progress.connect(self.databaseBuildProgress)
|
||||
self.databaseBuildThread.success.connect(self.databaseBuildSuccess)
|
||||
self.databaseBuildThread.error.connect(self.databaseBuildError)
|
||||
self.buildButton.setEnabled(False)
|
||||
self.databaseBuildThread.start()
|
||||
|
||||
@Slot(int, int)
|
||||
def databaseBuildProgress(self, i: int, total: int):
|
||||
if i < 5:
|
||||
self.progressBar.setMaximum(total)
|
||||
self.progressBar.setValue(i)
|
||||
|
||||
@Slot(str)
|
||||
def databaseBuildError(self, msg: str):
|
||||
QMessageBox.critical(self, "Error", msg)
|
||||
self.databaseBuildCleanUp()
|
||||
|
||||
@Slot()
|
||||
def databaseBuildSuccess(self):
|
||||
dbMemory = self.databaseBuildThread.conn
|
||||
|
||||
dbFileName, _ = QFileDialog.getSaveFileName(self, None, self.databaseFileName())
|
||||
if not dbFileName:
|
||||
self.databaseBuildCleanUp()
|
||||
QMessageBox.information(self, None, "User canceled operation.")
|
||||
return
|
||||
|
||||
dbDisk = sqlite3.connect(dbFileName)
|
||||
dbMemory.backup(dbDisk)
|
||||
self.databaseBuildCleanUp()
|
||||
|
||||
def databaseBuildCleanUp(self):
|
||||
self.databaseBuildThread.deleteLater()
|
||||
self.databaseBuildThread = None
|
||||
self.progressBar.setMaximum(0)
|
||||
self.progressBar.setValue(0)
|
||||
self.buildButton.setEnabled(True)
|
@ -89,12 +89,12 @@
|
||||
<translation>Continue</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../startup/databaseChecker.py" line="115"/>
|
||||
<location filename="../../startup/databaseChecker.py" line="117"/>
|
||||
<source>dialog.tryInitExistingDatabase</source>
|
||||
<translation>The existing database doesn't seem to be initialized properly, try initialize again?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../startup/databaseChecker.py" line="131"/>
|
||||
<location filename="../../startup/databaseChecker.py" line="133"/>
|
||||
<source>dialog.confirmNewDatabase</source>
|
||||
<translation>Database file does not exist. Create now?</translation>
|
||||
</message>
|
||||
@ -696,6 +696,11 @@ validation</translation>
|
||||
<source>tab.b30</source>
|
||||
<translation>B30</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcrEntry.ui" line="34"/>
|
||||
<source>tab.buildPHashDatabase</source>
|
||||
<translation>Build pHash Database</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TabOcr_B30</name>
|
||||
@ -1167,4 +1172,37 @@ validation</translation>
|
||||
<translation>Result (play rating)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>tabOcr_BuildPHashDatabase</name>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="33"/>
|
||||
<source>folders.title</source>
|
||||
<translation>Data Folders</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="41"/>
|
||||
<source>folders.songDir</source>
|
||||
<translation>Song jackets</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="62"/>
|
||||
<source>folders.charIconDir</source>
|
||||
<translation>Character icons</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="84"/>
|
||||
<source>options.title</source>
|
||||
<translation>Options</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="170"/>
|
||||
<source>resetButton</source>
|
||||
<translation>Reset</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="211"/>
|
||||
<source>buildButton</source>
|
||||
<translation>Build</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -89,12 +89,12 @@
|
||||
<translation>继续</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../startup/databaseChecker.py" line="115"/>
|
||||
<location filename="../../startup/databaseChecker.py" line="117"/>
|
||||
<source>dialog.tryInitExistingDatabase</source>
|
||||
<translation>现有的数据库似乎没有正确初始化,是否尝试再次初始化?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../startup/databaseChecker.py" line="131"/>
|
||||
<location filename="../../startup/databaseChecker.py" line="133"/>
|
||||
<source>dialog.confirmNewDatabase</source>
|
||||
<translation>数据库文件不存在,是否创建?</translation>
|
||||
</message>
|
||||
@ -695,6 +695,11 @@
|
||||
<source>tab.b30</source>
|
||||
<translation>B30</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcrEntry.ui" line="34"/>
|
||||
<source>tab.buildPHashDatabase</source>
|
||||
<translation>构建 pHash 数据库</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TabOcr_B30</name>
|
||||
@ -1166,4 +1171,37 @@
|
||||
<translation>结果(单曲 PTT)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>tabOcr_BuildPHashDatabase</name>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="33"/>
|
||||
<source>folders.title</source>
|
||||
<translation>数据文件夹</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="41"/>
|
||||
<source>folders.songDir</source>
|
||||
<translation>曲封</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="62"/>
|
||||
<source>folders.charIconDir</source>
|
||||
<translation>搭档头像</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="84"/>
|
||||
<source>options.title</source>
|
||||
<translation>选项</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="170"/>
|
||||
<source>resetButton</source>
|
||||
<translation>重置</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="211"/>
|
||||
<source>buildButton</source>
|
||||
<translation>构建</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
Reference in New Issue
Block a user