Allow select ocr language in SelectionDialog.
Support this in Recognizer and Translator.
This commit is contained in:
parent
e7e74ed20e
commit
6e85bfd7eb
@ -31,28 +31,28 @@ void Recognizer::applySettings()
|
|||||||
imageScale_ = settings.value (settings_names::imageScale,
|
imageScale_ = settings.value (settings_names::imageScale,
|
||||||
settings_values::imageScale).toInt ();
|
settings_values::imageScale).toInt ();
|
||||||
|
|
||||||
initEngine ();
|
initEngine (engine_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Recognizer::initEngine()
|
bool Recognizer::initEngine(tesseract::TessBaseAPI *&engine)
|
||||||
{
|
{
|
||||||
if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ())
|
if (tessDataDir_.isEmpty () || ocrLanguage_.isEmpty ())
|
||||||
{
|
{
|
||||||
emit error (tr ("Неверные параметры для OCR"));
|
emit error (tr ("Неверные параметры для OCR"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (engine_ != NULL)
|
if (engine != NULL)
|
||||||
{
|
{
|
||||||
delete engine_;
|
delete engine;
|
||||||
}
|
}
|
||||||
engine_ = new tesseract::TessBaseAPI();
|
engine = new tesseract::TessBaseAPI();
|
||||||
int result = engine_->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_),
|
int result = engine->Init(qPrintable (tessDataDir_), qPrintable (ocrLanguage_),
|
||||||
tesseract::OEM_DEFAULT);
|
tesseract::OEM_DEFAULT);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
emit error (tr ("Ошибка инициализации OCR: %1").arg (result));
|
emit error (tr ("Ошибка инициализации OCR: %1").arg (result));
|
||||||
delete engine_;
|
delete engine;
|
||||||
engine_ = NULL;
|
engine = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -61,9 +61,12 @@ bool Recognizer::initEngine()
|
|||||||
void Recognizer::recognize(ProcessingItem item)
|
void Recognizer::recognize(ProcessingItem item)
|
||||||
{
|
{
|
||||||
Q_ASSERT (!item.source.isNull ());
|
Q_ASSERT (!item.source.isNull ());
|
||||||
if (engine_ == NULL)
|
bool isCustomLanguage = (!item.ocrLanguage.isEmpty () &&
|
||||||
|
item.ocrLanguage != ocrLanguage_);
|
||||||
|
tesseract::TessBaseAPI* engine = (isCustomLanguage) ? NULL : engine_;
|
||||||
|
if (engine == NULL)
|
||||||
{
|
{
|
||||||
if (!initEngine ())
|
if (!initEngine (engine))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -71,12 +74,18 @@ void Recognizer::recognize(ProcessingItem item)
|
|||||||
|
|
||||||
Pix* image = prepareImage (item.source.toImage (), imageScale_);
|
Pix* image = prepareImage (item.source.toImage (), imageScale_);
|
||||||
Q_ASSERT (image != NULL);
|
Q_ASSERT (image != NULL);
|
||||||
engine_->SetImage (image);
|
engine->SetImage (image);
|
||||||
char* outText = engine_->GetUTF8Text();
|
char* outText = engine->GetUTF8Text();
|
||||||
QString result = QString (outText).trimmed ();
|
engine->Clear();
|
||||||
engine_->Clear();
|
|
||||||
cleanupImage (&image);
|
cleanupImage (&image);
|
||||||
|
|
||||||
|
QString result = QString (outText).trimmed ();
|
||||||
|
delete [] outText;
|
||||||
|
if (isCustomLanguage)
|
||||||
|
{
|
||||||
|
delete engine;
|
||||||
|
}
|
||||||
|
|
||||||
if (!result.isEmpty ())
|
if (!result.isEmpty ())
|
||||||
{
|
{
|
||||||
item.recognized = result;
|
item.recognized = result;
|
||||||
@ -86,5 +95,4 @@ void Recognizer::recognize(ProcessingItem item)
|
|||||||
{
|
{
|
||||||
emit error (tr ("Текст не распознан."));
|
emit error (tr ("Текст не распознан."));
|
||||||
}
|
}
|
||||||
delete [] outText;
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class Recognizer : public QObject
|
|||||||
void applySettings ();
|
void applySettings ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool initEngine ();
|
bool initEngine (tesseract::TessBaseAPI*&engine);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tesseract::TessBaseAPI* engine_;
|
tesseract::TessBaseAPI* engine_;
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
#include "SelectionDialog.h"
|
#include "SelectionDialog.h"
|
||||||
#include "ui_SelectionDialog.h"
|
#include "ui_SelectionDialog.h"
|
||||||
|
#include "LanguageHelper.h"
|
||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
SelectionDialog::SelectionDialog(QWidget *parent) :
|
SelectionDialog::SelectionDialog(const LanguageHelper &dictionary, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::SelectionDialog)
|
ui(new Ui::SelectionDialog), dictionary_ (dictionary),
|
||||||
|
languageMenu_ (new QMenu)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags (Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
|
setWindowFlags (Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint |
|
||||||
@ -15,6 +18,8 @@ SelectionDialog::SelectionDialog(QWidget *parent) :
|
|||||||
|
|
||||||
ui->label->setAutoFillBackground(false);
|
ui->label->setAutoFillBackground(false);
|
||||||
ui->label->installEventFilter (this);
|
ui->label->installEventFilter (this);
|
||||||
|
|
||||||
|
updateMenu ();
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionDialog::~SelectionDialog()
|
SelectionDialog::~SelectionDialog()
|
||||||
@ -22,6 +27,49 @@ SelectionDialog::~SelectionDialog()
|
|||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SelectionDialog::updateMenu()
|
||||||
|
{
|
||||||
|
Q_CHECK_PTR (languageMenu_);
|
||||||
|
languageMenu_->clear ();
|
||||||
|
QStringList languages = dictionary_.availableOcrLanguagesUi ();
|
||||||
|
if (languages.isEmpty ())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int max = 10;
|
||||||
|
|
||||||
|
if (languages.size () <= max)
|
||||||
|
{
|
||||||
|
foreach (const QString& language, languages)
|
||||||
|
{
|
||||||
|
languageMenu_->addAction (language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int subIndex = max;
|
||||||
|
QMenu* subMenu = NULL;
|
||||||
|
QString prevLetter;
|
||||||
|
foreach (const QString& language, languages)
|
||||||
|
{
|
||||||
|
QString curLetter = language.left (1);
|
||||||
|
if (++subIndex >= max && prevLetter != curLetter)
|
||||||
|
{
|
||||||
|
if (subMenu != NULL)
|
||||||
|
{
|
||||||
|
subMenu->setTitle (subMenu->title () + " - " + prevLetter);
|
||||||
|
}
|
||||||
|
subMenu = languageMenu_->addMenu (curLetter);
|
||||||
|
subIndex = 0;
|
||||||
|
}
|
||||||
|
prevLetter = curLetter;
|
||||||
|
subMenu->addAction (language);
|
||||||
|
}
|
||||||
|
subMenu->setTitle (subMenu->title () + " - " + prevLetter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
|
bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
|
||||||
{
|
{
|
||||||
if (object != ui->label)
|
if (object != ui->label)
|
||||||
@ -29,41 +77,24 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
|
|||||||
return QDialog::eventFilter (object, event);
|
return QDialog::eventFilter (object, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->type () == QEvent::MouseButtonPress)
|
if (event->type () == QEvent::Show)
|
||||||
|
{
|
||||||
|
startSelectPos_ = currentSelectPos_ = QPoint ();
|
||||||
|
}
|
||||||
|
else if (event->type () == QEvent::MouseButtonPress)
|
||||||
{
|
{
|
||||||
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
||||||
if (mouseEvent->button () == Qt::LeftButton)
|
if ((mouseEvent->button () == Qt::LeftButton ||
|
||||||
|
mouseEvent->button () == Qt::RightButton) && startSelectPos_.isNull ())
|
||||||
{
|
{
|
||||||
startSelectPos_ = mouseEvent->pos ();
|
startSelectPos_ = mouseEvent->pos ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event->type () == QEvent::MouseButtonRelease)
|
|
||||||
{
|
|
||||||
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
|
||||||
if (mouseEvent->button () == Qt::LeftButton)
|
|
||||||
{
|
|
||||||
if (startSelectPos_.isNull () || currentPixmap_.isNull ())
|
|
||||||
{
|
|
||||||
QDialog::eventFilter (object, event);
|
|
||||||
}
|
|
||||||
QPoint endPos = mouseEvent->pos ();
|
|
||||||
QRect selection = QRect (startSelectPos_, endPos).normalized ();
|
|
||||||
startSelectPos_ = currentSelectPos_ = QPoint ();
|
|
||||||
QPixmap selectedPixmap = currentPixmap_.copy (selection);
|
|
||||||
if (!selectedPixmap.isNull ())
|
|
||||||
{
|
|
||||||
ProcessingItem item;
|
|
||||||
item.source = selectedPixmap;
|
|
||||||
item.screenPos = selection.topLeft ();
|
|
||||||
emit selected (item);
|
|
||||||
accept ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (event->type () == QEvent::MouseMove)
|
else if (event->type () == QEvent::MouseMove)
|
||||||
{
|
{
|
||||||
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
||||||
if (mouseEvent->buttons () & Qt::LeftButton)
|
if ((mouseEvent->buttons () & Qt::LeftButton ||
|
||||||
|
mouseEvent->buttons () & Qt::RightButton) && !startSelectPos_.isNull ())
|
||||||
{
|
{
|
||||||
currentSelectPos_ = mouseEvent->pos ();
|
currentSelectPos_ = mouseEvent->pos ();
|
||||||
ui->label->repaint ();
|
ui->label->repaint ();
|
||||||
@ -79,7 +110,44 @@ bool SelectionDialog::eventFilter(QObject* object, QEvent* event)
|
|||||||
painter.drawRect (selection);
|
painter.drawRect (selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (event->type () == QEvent::MouseButtonRelease)
|
||||||
|
{
|
||||||
|
QMouseEvent* mouseEvent = static_cast <QMouseEvent*> (event);
|
||||||
|
if (mouseEvent->button () == Qt::LeftButton ||
|
||||||
|
mouseEvent->button () == Qt::RightButton)
|
||||||
|
{
|
||||||
|
if (startSelectPos_.isNull () || currentPixmap_.isNull ())
|
||||||
|
{
|
||||||
|
return QDialog::eventFilter (object, event);
|
||||||
|
}
|
||||||
|
QPoint endPos = mouseEvent->pos ();
|
||||||
|
QRect selection = QRect (startSelectPos_, endPos).normalized ();
|
||||||
|
QPixmap selectedPixmap = currentPixmap_.copy (selection);
|
||||||
|
if (!selectedPixmap.isNull ())
|
||||||
|
{
|
||||||
|
ProcessingItem item;
|
||||||
|
item.source = selectedPixmap;
|
||||||
|
item.screenPos = selection.topLeft ();
|
||||||
|
|
||||||
|
if (mouseEvent->button () == Qt::RightButton &&
|
||||||
|
!languageMenu_->children ().isEmpty ())
|
||||||
|
{
|
||||||
|
QAction* action = languageMenu_->exec (QCursor::pos ());
|
||||||
|
if (action == NULL)
|
||||||
|
{
|
||||||
|
reject ();
|
||||||
|
return QDialog::eventFilter (object, event);
|
||||||
|
}
|
||||||
|
item.ocrLanguage = dictionary_.ocrUiToCode (action->text ());
|
||||||
|
Q_ASSERT (!item.ocrLanguage.isEmpty ());
|
||||||
|
item.sourceLanguage = dictionary_.translateForOcrCode (item.ocrLanguage);
|
||||||
|
Q_ASSERT (!item.sourceLanguage.isEmpty ());
|
||||||
|
}
|
||||||
|
emit selected (item);
|
||||||
|
accept ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return QDialog::eventFilter (object, event);
|
return QDialog::eventFilter (object, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,19 +3,21 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
#include "ProcessingItem.h"
|
#include "ProcessingItem.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class SelectionDialog;
|
class SelectionDialog;
|
||||||
}
|
}
|
||||||
|
class LanguageHelper;
|
||||||
|
|
||||||
class SelectionDialog : public QDialog
|
class SelectionDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SelectionDialog(QWidget *parent = 0);
|
explicit SelectionDialog(const LanguageHelper& dictionary, QWidget *parent = 0);
|
||||||
~SelectionDialog();
|
~SelectionDialog();
|
||||||
|
|
||||||
bool eventFilter (QObject *object, QEvent *event);
|
bool eventFilter (QObject *object, QEvent *event);
|
||||||
@ -25,12 +27,15 @@ class SelectionDialog : public QDialog
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setPixmap (QPixmap pixmap);
|
void setPixmap (QPixmap pixmap);
|
||||||
|
void updateMenu ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SelectionDialog *ui;
|
Ui::SelectionDialog *ui;
|
||||||
|
const LanguageHelper& dictionary_;
|
||||||
QPoint startSelectPos_;
|
QPoint startSelectPos_;
|
||||||
QPoint currentSelectPos_;
|
QPoint currentSelectPos_;
|
||||||
QPixmap currentPixmap_;
|
QPixmap currentPixmap_;
|
||||||
|
QMenu* languageMenu_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SELECTIONDIALOG_H
|
#endif // SELECTIONDIALOG_H
|
||||||
|
@ -39,12 +39,14 @@ void Translator::applySettings()
|
|||||||
void Translator::translate(ProcessingItem item)
|
void Translator::translate(ProcessingItem item)
|
||||||
{
|
{
|
||||||
Q_ASSERT (!item.recognized.isEmpty ());
|
Q_ASSERT (!item.recognized.isEmpty ());
|
||||||
if (translationLanguage_.isEmpty ())
|
QString sourceLanguage = item.sourceLanguage.isEmpty () ? sourceLanguage_ :
|
||||||
|
item.sourceLanguage;
|
||||||
|
if (translationLanguage_.isEmpty () || sourceLanguage.isEmpty ())
|
||||||
{
|
{
|
||||||
emit error (tr ("Неверные парметры для перевода."));
|
emit error (tr ("Неверные парметры для перевода."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QUrl url (translateBaseUrl.arg (item.recognized, sourceLanguage_, translationLanguage_));
|
QUrl url (translateBaseUrl.arg (item.recognized, sourceLanguage, translationLanguage_));
|
||||||
QNetworkReply* reply = network_.get (QNetworkRequest (url));
|
QNetworkReply* reply = network_.get (QNetworkRequest (url));
|
||||||
items_.insert (reply, item);
|
items_.insert (reply, item);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user