yagf-0.9.2.1/ 0000775 0001750 0001750 00000000000 12250673416 013337 5 ustar parallels parallels yagf-0.9.2.1/README 0000664 0001750 0001750 00000000466 12247205425 014222 0 ustar parallels parallels For more information and system requirements see DESCRIPTION file.
This is a beta version so many things are not yet implemented as they are supposed to.
The main things to do are
- adding more image prepocessing features
- adding packet recognition
Contributors are welcome.
Contact me via anb@symmetrica.net. yagf-0.9.2.1/src/ 0000775 0001750 0001750 00000000000 12250673434 014126 5 ustar parallels parallels yagf-0.9.2.1/src/spellchecker.cpp 0000664 0001750 0001750 00000020636 12250140707 017275 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "spellchecker.h"
SpellChecker::SpellChecker(QTextEdit *textEdit): m_textEdit(textEdit)
{
m_regExp = new QRegExp("[^\\s]*");
//m_cursor= new QTextCursor(m_textEdit->document());
spell_config1 = new_aspell_config();
spell_config2 = new_aspell_config();
aspell_config_replace(spell_config1, "lang", m_lang1.toAscii());
aspell_config_replace(spell_config2, "lang", m_lang2.toAscii());
aspell_config_replace(spell_config1, "encoding", "utf-8");
aspell_config_replace(spell_config2, "encoding", "utf-8");
m_map = new StringMap();
m_map->insert("ruseng", "ru");
m_map->insert("rus", "ru");
m_map->insert("bul", "bg");
m_map->insert("cze", "cs");
m_map->insert("dan", "da");
m_map->insert("dut", "nl");
m_map->insert("ell", "el");
m_map->insert("eng", "en");
m_map->insert("est", "et");
m_map->insert("fin", "fi");
m_map->insert("fra", "fr");
m_map->insert("ger", "de");
m_map->insert("gerf", "de-alt");
m_map->insert("heb", "he");
m_map->insert("hrv", "hr");
m_map->insert("hun", "hu");
m_map->insert("ita", "it");
m_map->insert("lav", "lv");
m_map->insert("lit", "lt");
m_map->insert("nor", "no");
m_map->insert("pol", "pl");
m_map->insert("por", "pt_PT");
m_map->insert("rum", "ro");
m_map->insert("slo", "sl");
m_map->insert("slk", "sk");
m_map->insert("spa", "es");
m_map->insert("srp", "sr");
m_map->insert("swe", "sv");
m_map->insert("swef", "sv");
m_map->insert("tur", "tr");
m_map->insert("ukr", "uk");
spell_checker1 = 0;
spell_checker2 = 0;
setLanguage("ruseng");
dictList = new QStringList();
}
void SpellChecker::enumerateDicts()
{
AspellConfig *config;
AspellDictInfoList *dlist;
AspellDictInfoEnumeration *dels;
const AspellDictInfo *entry;
config = new_aspell_config();
/* the returned pointer should _not_ need to be deleted */
dlist = get_aspell_dict_info_list(config);
/* config is no longer needed */
delete_aspell_config(config);
dels = aspell_dict_info_list_elements(dlist);
while ((entry = aspell_dict_info_enumeration_next(dels)) != 0) {
dictList->append(entry->code);
}
delete_aspell_dict_info_enumeration(dels);
}
bool SpellChecker::hasDict(const QString &shname)
{
return dictList->contains(m_map->value(shname));
}
SpellChecker::~SpellChecker()
{
delete m_regExp;
delete m_map;
delete_aspell_speller(spell_checker1);
delete_aspell_speller(spell_checker2);
delete_aspell_config(spell_config1);
delete_aspell_config(spell_config2);
delete dictList;
}
void SpellChecker::setLanguage(const QString &lang)
{
delete_aspell_speller(spell_checker1);
delete_aspell_speller(spell_checker2);
bad_language.clear();
m_lang2 = "en";
m_lang1 = m_map->value(lang, QString("en"));
if (lang == "rus_fra") {
m_lang1 = "ru";
m_lang2 = "fr";
} else if (lang == "rus_ger") {
m_lang1 = "ru";
m_lang2 = "de";
} else if (lang == "rus_spa") {
m_lang1 = "ru";
m_lang2 = "es";
}
aspell_config_replace(spell_config1, "lang", m_lang1.toAscii());
aspell_config_replace(spell_config2, "lang", m_lang2.toAscii());
AspellCanHaveError *possible_err = new_aspell_speller(spell_config1);
spell_checker1 = 0;
if (aspell_error_number(possible_err) == 0)
spell_checker1 = to_aspell_speller(possible_err);
else
delete_aspell_can_have_error(possible_err);
possible_err = new_aspell_speller(spell_config2);
spell_checker2 = 0;
if (aspell_error_number(possible_err) == 0)
spell_checker2 = to_aspell_speller(possible_err);
else
delete_aspell_can_have_error(possible_err);
// Check absent dictionary
if (spell_checker1 == 0)
bad_language = m_lang1;
if (spell_checker2 == 0)
bad_language = m_lang2;
}
bool SpellChecker::spellCheck()
{
if ((spell_checker1 == 0) || (spell_checker2 == 0)) {
QPixmap icon;
icon.load(":/warning.png");
QMessageBox messageBox(QMessageBox::NoIcon, "YAGF", QObject::trUtf8("Required spelling dictionary (%1) is not found.\nSpell-checking is disabled.\nTry to install an appropriate aspell dictionary.").arg(bad_language),
QMessageBox::Ok, 0);
messageBox.setIconPixmap(icon);
messageBox.exec();
return false;
}
QTextCursor cursor(m_textEdit->document());
while (!cursor.isNull() && !cursor.atEnd()) {
_checkWord(&cursor);
QTextCursor oldc = cursor;
if (!cursor.movePosition(QTextCursor::NextWord,
QTextCursor::MoveAnchor))
break;
//cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor);
//cursor = m_textEdit->document()->find(*m_regExp, cursor);
int oldpos = oldc.position();
int newpos = cursor.position();
if (abs(newpos - oldpos) < 3)
cursor.setPosition(newpos + 1);
}
if (!cursor.isNull())
_checkWord(&cursor);
return true;
}
void SpellChecker::unSpellCheck()
{
QTextCursor cursor(m_textEdit->document());
QTextCharFormat fmt = cursor.charFormat();
fmt.setUnderlineStyle(QTextCharFormat::NoUnderline);
cursor.select(QTextCursor::Document);
cursor.setCharFormat(fmt);
cursor.clearSelection();
}
void SpellChecker::_checkWord(QTextCursor *cursor)
{
cursor->select(QTextCursor::WordUnderCursor);
QString selText = cursor->selectedText();
static const QRegExp nonDigits("\\D");
if (!selText.contains(nonDigits))
return;
selText = selText.remove(QString::fromUtf8("«"));
selText = selText.remove(QString::fromUtf8("»"));
//selText = selText.remove("\"");
//selText = selText.remove("(");
//selText = selText.remove(")");
QByteArray ba = selText.toUtf8();
if ((aspell_speller_check(spell_checker1, ba.data(), ba.size()) == 0) &&
(aspell_speller_check(spell_checker2, ba.data(), ba.size()) == 0)) {
QTextCharFormat fmt = cursor->charFormat();
fmt.setUnderlineColor(QColor(Qt::red));
fmt.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
cursor->setCharFormat(fmt);
} else {
QTextCharFormat fmt = cursor->charFormat();
fmt.setUnderlineStyle(QTextCharFormat::NoUnderline);
cursor->setCharFormat(fmt);
}
cursor->clearSelection();
}
void SpellChecker::checkWord()
{
if ((spell_checker1 == 0) || (spell_checker2 == 0))
return;
QTextCursor cursor = m_textEdit->textCursor();
_checkWord(&cursor);
}
QStringList SpellChecker::suggestions()
{
QStringList sl;
if ((spell_checker1 == 0) || (spell_checker2 == 0))
return sl;
QTextCursor cursor = m_textEdit->textCursor();
cursor.select(QTextCursor::WordUnderCursor);
QString word = cursor.selectedText();
QByteArray ba = word.toUtf8();
if ((aspell_speller_check(spell_checker2, ba.data(), ba.size()) != 0)||(aspell_speller_check(spell_checker1, ba.data(), ba.size()) != 0))
return sl;
const struct AspellWordList * awl = aspell_speller_suggest(spell_checker1, ba.data(), ba.size());
if(aspell_word_list_size(awl) > 0) {
struct AspellStringEnumeration * ase = aspell_word_list_elements(awl);
int i = 0;
while ((!aspell_string_enumeration_at_end(ase))&&(i < 10)) {
const char * text = aspell_string_enumeration_next(ase);
sl << QString::fromUtf8(text);
i++;
}
delete_aspell_string_enumeration(ase);
}
return sl;
}
yagf-0.9.2.1/src/popplerdialog.ui 0000664 0001750 0001750 00000015641 12247205425 017332 0 ustar parallels parallels
PopplerDialog00320252Import from PDF:/images/application_pdf.png:/images/application_pdf.pngFile Name10Select...Pages2FromspinBox11199912242TospinBox_2001999Qt::Horizontal402001Entire DocumentQt::Vertical2040Qt::HorizontalQDialogButtonBox::Cancel|QDialogButtonBox::OkbuttonBoxrejected()PopplerDialogreject()316260286274buttonBoxaccepted()PopplerDialogaccept()248254157274
yagf-0.9.2.1/src/tpagecollection.cpp 0000664 0001750 0001750 00000017636 12250140707 020013 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "tpagecollection.h"
#include "qsnippet.h"
#ifdef TIFF_IO
#include "qxttiffiohandler.h"
#endif
#include "settings.h"
#include
#include
#include
PageCollection * PageCollection::m_instance = NULL;
PageCollection::PageCollection(QObject *parent) :
QObject(parent)
{
index = -1;
pid = 0;
}
PageCollection::PageCollection(const PageCollection &)
{
}
PageCollection::~PageCollection()
{
clear();
}
bool PageCollection::appendPage(const QString &fileName)
{
#ifdef TIFF_IO
if (fileName.endsWith(".tif", Qt::CaseInsensitive) || fileName.endsWith(".tiff", Qt::CaseInsensitive)) {
QXtTiffIOHandler * toh = new QXtTiffIOHandler();
QFile f(fileName);
f.open(QIODevice::ReadOnly);
toh->setDevice(&f);
if (toh->canRead()) {
if (toh->imageCount() == 1) {
delete toh;
appendPage(fileName);
return true;
} else {
for (int i = 0; i < toh->imageCount(); i++) {
QImage img;
toh->jumpToImage(i);
toh->read(&img);
QString nfn = Settings::instance()->workingDir() + QString("tiff-page-%1.jpg").arg(i+1);
img.save(nfn, "JPEG");
appendPage(nfn);
QApplication::processEvents();
}
delete toh;
return true;
}
} else return false;
} else
#endif // TIFF_IO
{
Page * p = new Page(++pid);
connect(p,SIGNAL(refreshView()), this, SIGNAL(loadPage()));
if (p->loadFile(fileName)) {
pages.append(p);
index = pages.count() - 1;
emit addSnippet(index);
return true;
} else return false;
}
}
int PageCollection::count()
{
return pages.count();
}
bool PageCollection::makePageCurrent(int index)
{
this->index = index;
return index < pages.count();
}
bool PageCollection::makePageCurrentByID(int id)
{
return makePageCurrent(id2Index(id)) >= 0;
}
void PageCollection::setBeforeFirst()
{
index = -1;
}
bool PageCollection::makeNextPageCurrent()
{
index++;
if (index < count())
return true;
index = -1;
return false;
}
QSnippet *PageCollection::snippet()
{
if (!cp()) return NULL;
QSnippet * s = new QSnippet();
s->setPage(cp()->pageID(), cp()->fileName(), cp()->thumbnail());
return s;
}
QPixmap PageCollection::pixmap()
{
if (!cp()) return QPixmap();
return cp()->displayPixmap();
}
void PageCollection::savePageForRecognition(const QString &fileName)
{
if (!cp()) return;
cp()->savePageForRecognition(fileName);
}
void PageCollection::saveRawBlockForRecognition(QRect r, const QString &fileName)
{
if (!cp()) return;
cp()->saveRawBlockForRecognition(r, fileName);
}
void PageCollection::saveBlockForRecognition(QRect r, const QString &fileName, const QString &format)
{
if (!cp()) return;
cp()->saveBlockForRecognition(r, fileName, format);
}
void PageCollection::saveBlockForRecognition(int index, const QString &fileName)
{
if (!cp()) return;
if (index == 0)
cp()->sortBlocksInternal();
cp()->saveBlockForRecognition(index, fileName);
}
int PageCollection::blockCount()
{
if (!cp()) return 0;
return cp()->blockCount();
}
Block PageCollection::getBlock(const QRect &r)
{
Block block(0,0,0,0);
if (!cp()) return block;
return cp()->getBlock(r);
}
Block PageCollection::getBlock(int index)
{
Block block(0,0,0,0);
if (!cp()) return block;
return cp()->getBlock(index);
}
void PageCollection::selectBlock(const QRect &r)
{
if (!cp()) return;
cp()->selectBlock(r);
}
Block PageCollection::getSelectedBlock()
{
Block block(0,0,0,0);
if (!cp()) return block;
return cp()->getSelectedBlock();
}
bool PageCollection::pageValid()
{
return cp() != 0;
}
QString PageCollection::fileName()
{
if (!cp())
return "";
return cp()->fileName();
}
bool PageCollection::savePageAsImage(const QString &fileName, const QString &format)
{
if (!cp())
return false;
return cp()->savePageAsImage(fileName, format);
}
bool PageCollection::isDeskewed()
{
if (cp())
return cp()->isDeskewed();
return false;
}
bool PageCollection::isPreprocessed()
{
if (cp())
return cp()->isPreprocessed();
return false;
}
qreal PageCollection::getRotation()
{
if (cp())
return cp()->getRotation();
return 0;
}
void PageCollection::setRotation(const qreal value)
{
if (cp())
cp()->rotate(value);
}
void PageCollection::setDeskewed(const bool value)
{
if (cp())
cp()->setDeskewed(value);
}
void PageCollection::setPreprocessed(const bool value)
{
if (cp())
cp()->setPreprocessed(value);
}
void PageCollection::reloadPage()
{
emit loadPage();
}
void PageCollection::makeLarger()
{
if (!cp()) return;
cp()->makeLarger();
emit loadPage();
}
void PageCollection::makeSmaller()
{
if (!cp()) return;
cp()->makeSmaller();
emit loadPage();
}
void PageCollection::rotate90CW()
{
if (!cp()) return;
cp()->rotate90CW();
emit loadPage();
}
void PageCollection::rotate90CCW()
{
if (!cp()) return;
cp()->rotate90CCW();
emit loadPage();
}
void PageCollection::rotate180()
{
if (!cp()) return;
cp()->rotate180();
emit loadPage();
}
void PageCollection::deskew()
{
if (!cp()) return;
cp()->deskew();
emit loadPage();
}
void PageCollection::blockAllText()
{
if (!cp()) return;
cp()->blockAllText();
emit loadPage();
}
bool PageCollection::splitPage(bool preprocess)
{
if (!cp()) return false;
bool res = cp()->splitPage(preprocess);
emit loadPage();
return res;
}
void PageCollection::addBlock(const QRect &rect)
{
if (!cp()) return;
Block block(rect.x(), rect.y(), rect.width(), rect.height());
cp()->addBlock(block);
}
void PageCollection::deleteBlock(const QRect &rect)
{
if (!cp()) return;
cp()->deleteBlock(rect);
}
void PageCollection::clearBlocks()
{
if (!cp()) return;
cp()->clearBlocks();
}
void PageCollection::clear()
{
foreach (Page * p, pages) {
delete p;
}
pages.clear();
emit cleared();
index = -1;
pid = 0;
}
Page *PageCollection::cp()
{
if ((index < 0)|| (index >= count()))
return (Page*) 0;
return pages.at(index);
}
int PageCollection::id2Index(int id)
{
foreach (Page *p, pages) {
if (p->pageID() == id)
return pages.indexOf(p);
}
return -1;
}
void PageCollection::pageSelected(int id)
{
makePageCurrent(id2Index(id));
emit loadPage();
}
void PageCollection::pageRemoved(int id)
{
int index = id2Index(id);
if (index >= 0) {
delete pages.at(index);
pages.remove(index);
}
if (index >= pages.count())
index = pages.count() - 1;
makePageCurrent(index);
emit loadPage();
}
PageCollection *PageCollection::instance()
{
if (!m_instance)
m_instance = new PageCollection();
return m_instance;
}
void PageCollection::clearCollection()
{
if (m_instance)
m_instance->clear();
}
yagf-0.9.2.1/src/pdfextractor.cpp 0000664 0001750 0001750 00000011461 12247205425 017337 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "pdfextractor.h"
#include
#include
#include
#include
#include
#include
#include
class PDFThread : public QThread
{
public:
explicit PDFThread(PDFExtractor * parent) : QThread()
{
mparent = parent;
}
virtual void run()
{
QProcess process;
// connect(this, SIGNAL(finished()), mparent, SIGNAL(finished()), Qt::QueuedConnection);
// connect(this, SIGNAL(terminated()), mparent, SIGNAL(finished()), Qt::QueuedConnection);
connect(mparent, SIGNAL(terminate()), this, SLOT(terminate()));
connect (mparent, SIGNAL(killProcess()), &process, SLOT(kill()), Qt::QueuedConnection);
connect (mparent, SIGNAL(terminateProcess()), &process, SLOT(terminate()), Qt::QueuedConnection);
process.start(command, arguments);
process.waitForFinished(1600000);
}
void setProcess(const QString &cmd, const QStringList &args)
{
command = cmd;
arguments.clear();
arguments.append(args);
}
private:
QString command;
QStringList arguments;
PDFExtractor * mparent;
};
PDFExtractor::PDFExtractor(QObject *parent) :
QObject(parent)
{
}
void PDFExtractor::setCommandStringPaged(const QString &cmdStr)
{
commandStringPaged = cmdStr;
}
void PDFExtractor::setCommandStringEntire(const QString &cmdStr)
{
commandStringEntire = cmdStr;
}
void PDFExtractor::setOutputDir(const QString &value)
{
outputDir = value;
}
QString PDFExtractor::getOutputDir()
{
return outputDir;
}
void PDFExtractor::setOutputExtension(const QString &value)
{
outputExtension = value;
}
QString PDFExtractor::getOutputExtension()
{
return outputExtension;
}
void PDFExtractor::setOutputPrefix(const QString &value)
{
outputPrefix = value;
}
QString PDFExtractor::getOutputPrefix()
{
return outputPrefix;
}
void PDFExtractor::setResolution(const QString &value)
{
resolution = value;
}
QString PDFExtractor::getResolution()
{
return resolution;
}
void PDFExtractor::setSourcePDF(const QString &value)
{
sourcePDF = value;
}
QString PDFExtractor::getSourcePDF()
{
return sourcePDF;
}
void PDFExtractor::setStartPage(const QString &value)
{
startPage = value;
}
QString PDFExtractor::getStartPage()
{
return startPage;
}
void PDFExtractor::setStopPage(const QString &value)
{
stopPage = value;
}
QString PDFExtractor::getStopPage()
{
return stopPage;
}
void PDFExtractor::cancel()
{
emit killProcess();
emit terminateProcess();
emit terminate();
}
void PDFExtractor::execInternal(const QString &command, const QStringList &arguments)
{
canceled = false;
filters.clear();
filters << QString("page*.%1").arg(getOutputExtension());
PDFThread thread(this);
thread.setProcess(command, arguments);
thread.start();
lastPage = 0;
while (!thread.isFinished()) {
QDir dir;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Size | QDir::Reversed);
dir.setSorting(QDir::Name);
dir.setPath(outputDir);
QFileInfoList fil;
fil = dir.entryInfoList(filters, QDir::Files, QDir::Name);
int lastI = 0;
for (int i =lastPage; i < fil.count() - 1; i++) {
emit addPage(fil.at(i).absoluteFilePath());
lastI = i;
QApplication::processEvents();
}
lastPage = lastI;
}
QDir dir;
dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
dir.setSorting(QDir::Size | QDir::Reversed);
dir.setSorting(QDir::Name);
dir.cd(outputDir);
QFileInfoList fil;
fil = dir.entryInfoList(filters, QDir::Files, QDir::Name);
for (int i = 0; i < fil.count(); i++) {
emit addPage(fil.at(i).absoluteFilePath());
QApplication::processEvents();
}
emit finished();
}
yagf-0.9.2.1/src/forcelocaledialog.cpp 0000600 0001750 0001750 00000004147 12250171445 020257 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "forcelocaledialog.h"
#include "ui_forcelocaledialog.h"
ForceLocaleDialog::ForceLocaleDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ForceLocaleDialog)
{
ui->setupUi(this);
this->setWindowTitle("Choose UI Language");
ui->groupBox->setTitle("Choose Language");
ui->radioButton->setText("English");
ui->radioButton_2->setText("Russian");
ui->radioButton_3->setText("Defined by locale");
ui->label->setText("Restart the program for the changes to take effect");
ui->buttonBox->buttons()[1]->setText("&Cancel");
ui->buttonBox->buttons()[0]->setText("&OK");
}
ForceLocaleDialog::~ForceLocaleDialog()
{
delete ui;
}
void ForceLocaleDialog::setOption(Locales option)
{
switch(option) {
case ForceLocaleDialog::NoLocale:
ui->radioButton->setChecked(true);
break;
case ForceLocaleDialog::RussianLocale:
ui->radioButton_2->setChecked(true);
break;
case ForceLocaleDialog::DefaultLocale:
ui->radioButton_3->setChecked(true);
break;
default:
break;
}
}
ForceLocaleDialog::Locales ForceLocaleDialog::getOption()
{
if (ui->radioButton->isChecked())
return ForceLocaleDialog::NoLocale;
if (ui->radioButton_2->isChecked())
return ForceLocaleDialog::RussianLocale;
return ForceLocaleDialog::DefaultLocale;
}
yagf-0.9.2.1/src/qsnippet.cpp 0000664 0001750 0001750 00000002471 12247205425 016476 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "qsnippet.h"
QSnippet::QSnippet(QListWidget *parent) :
QListWidgetItem(parent)
{
}
bool QSnippet::setPage(int id, const QString &name, const QImage &image)
{
if (image.isNull()) {
QImage img(name);
if (img.isNull())
return false;
setIcon(QPixmap::fromImage(img));
}
else
setIcon(QPixmap::fromImage(image));
this->name = name;
setToolTip(name);
pid = id;
return true;
}
QString QSnippet::getName()
{
return name;
}
int QSnippet::pageID()
{
return pid;
}
yagf-0.9.2.1/src/CCAnalysis.cpp 0000664 0001750 0001750 00000014141 12247205425 016621 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "CCAnalysis.h"
#include
#include
RotationCropper::RotationCropper(QImage * image, QRgb color, int dtr)
{
this->image = image;
darksCount = 0;
lightsCount = 0;
minval = 0;
maxval = 0;
//clAltCount = 0;
darktr = dtr;
whitetr = 650;
clBrighttoWidthtr = 0.1;
//QRgb * line = (QRgb *) image->scanLine(0);
whitePixel = color;
//replaceColor = color;
}
RotationCropper::~RotationCropper() {}
QRect RotationCropper::crop()
{
y1 = 0;
int tolerance = 3;
recolor();
for (int y = 0; y < image->height(); y ++) {
if (checkHorzLine(y)) {
tolerance--;
if (tolerance == 0) {
y1 = y;
break;
}
} else
tolerance = 3;
}
y2 = image->height()-1;
tolerance = 3;
for (int y = y2; y >= 0; y--) {
if (checkHorzLine(y)) {
tolerance--;
if (tolerance == 0) {
y2 = y;
break;
}
} else
tolerance = 3;
}
x1 = 0;
tolerance = 3;
for (int x = x1; x < image->width(); x++) {
if (checkVertLine(x)) {
tolerance--;
if (tolerance == 0) {
x1 = x;
break;
}
} else
tolerance = 3;
}
x2 = image->width()-1;
tolerance = 3;
for (int x = x2; x >= 0; x--) {
if (checkVertLine(x)) {
tolerance--;
if (tolerance == 0) {
x2 = x;
break;
}
} else
tolerance = 3;
}
return QRect(x1, y1, x2-x1, y2-y1);
}
void RotationCropper::recolor()
{
QColor repColor(1,2,3);
for (int y = 0; y < image->height(); y++) {
QRgb * line = (QRgb *) image->scanLine(y);
for (int x = 0; x < image->width(); x++) {
if (line[x] == whitePixel )
line[x] = repColor.rgb();
else break;
}
for (int x = image->width() - 1; x >= 0; x--) {
if (line[x] == whitePixel )
line[x] = repColor.rgb();
else break;
}
}
}
bool RotationCropper::checkHorzLine(int y)
{
int skipCount = 0;
darksCount = 0;
lightsCount = 0;
minval = 800;
maxval = 0;
whitesCount = 0;
//clAltCount = 0;
whiteAlt = 0;
//int maxlstripe = 0;
//int currentlstripe = 0;
QRgb * line = (QRgb *) image->scanLine(y);
for (int i = 0; i < image->width(); i++) {
if ((qRed(line[i]) == 1) && (qGreen(line[i]) == 2) && (qBlue(line[i]) == 3)) {
skipCount++;
continue;
}
int pixel = qRed(line[i]) + qGreen(line[i]) + qBlue(line[i]);
if (pixel <= darktr) {
darksCount++;
// if (currentlstripe > maxlstripe) maxlstripe = currentlstripe;
// currentlstripe = 0;
} else {
lightsCount++;
// currentlstripe++;
if (pixel >= whitetr) {
whitesCount++;
if (whiteAlt == 0) {
whiteAlt = 1;
clWhiteCount++;
}
} else
whiteAlt = 0;
}
minval = pixel < minval ? pixel : minval;
maxval = pixel > maxval ? pixel : maxval;
}
qreal d = image->width() - skipCount;
if (d == 0)
return false;
clBrighttoWidth = (qreal)lightsCount/d;
if (clBrighttoWidth <= clBrighttoWidthtr)
return false;
if (maxval - minval < 40)
return false;
//if (clAltCount < 10)
// return false;
//if (maxlstripe < 10)
// return false;
// if ((clWhiteCount > 0)&&(clWhiteCount < 3))
// return false;
return true;
}
bool RotationCropper::checkVertLine(int x)
{
int skipCount = 0;
darksCount = 0;
lightsCount = 0;
minval = 800;
maxval = 0;
whitesCount = 0;
//clAltCount = 0;
whiteAlt = 0;
//int curline =0;
for (int y = 0; y < image->height(); y++) {
QRgb * line = (QRgb *) image->scanLine(y);
if ((qRed(line[x]) == 1) && (qGreen(line[x]) == 2) && (qBlue(line[x]) == 3)) {
skipCount++;
continue;
}
int pixel = qRed(line[x]) + qGreen(line[x]) + qBlue(line[x]);
if (pixel <= darktr) {
darksCount++;
// if (curline) {
// clAltCount++;
// curline = 0;
// }
} else {
lightsCount++;
// if (!curline) {
// clAltCount++;
// curline = 1;
// }
if (pixel >= whitetr) {
whitesCount++;
if (whiteAlt == 0) {
whiteAlt = 1;
clWhiteCount++;
}
} else
whiteAlt = 0;
}
minval = pixel < minval ? pixel : minval;
maxval = pixel > maxval ? pixel : maxval;
}
qreal d = image->height() - skipCount;
if (d == 0)
return false;
clBrighttoWidth = (qreal)lightsCount/d;
if (clBrighttoWidth <= clBrighttoWidthtr)
return false;
if (maxval - minval < 40)
return false;
// if (clAltCount < 10)
// return false;
if ((clWhiteCount > 0)&&(clWhiteCount < 3))
return false;
return true;
}
yagf-0.9.2.1/src/ycommon.h 0000664 0001750 0001750 00000002131 12247205425 015752 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef YCOMMMON_H
#define YCOMMMON_H
#include
#include
#include
#include
typedef QList QPointList;
inline QRect QRectF2Rect(const QRectF &rf)
{
QRect r;
r.setX(rf.x());
r.setY(rf.y());
r.setWidth(rf.width());
r.setHeight(rf.height());
return r;
}
#endif
yagf-0.9.2.1/src/main.cpp 0000775 0001750 0001750 00000005141 12250171073 015552 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "mainform.h"
#include "settings.h"
void parseCmdLine(const QStringList &args)
{
foreach (const QString &arg, args){
if (arg == "-h" || arg == "--help") {
printf("Using:\n"
" yagf\n"
" yagf \n"
" yagf [file name [file name]...]\n"
"YAGF is a graphical interface for cuneiform and tesseract.\n"
"\n"
"Keys:\n"
" -h, --help\t Show this message and exit\n"
" -V, --version\t Show version string and exit\n");
exit(0);
} else if (arg == "-V" || arg == "--version") {
printf("YAGF version: %s\n", version.toUtf8().constData());
exit(0);
}
}
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
parseCmdLine(app.arguments());
Settings * settings = Settings::instance();
settings->readSettings(settings->workingDir());
settings->writeSettings();
QTranslator translator;
QString qmName = "yagf_" + QLocale::system().name();
if (settings->useRussianLocale())
qmName = "yagf_ru";
if (!settings->useNoLocale()) {
translator.load(qmName, QString(QML_INSTALL_PATH));
app.installTranslator(&translator);
settings->makeLanguageMaps();
}
QTranslator translator2;
if (settings->useRussianLocale())
translator2.load("qt_ru_RU", QLibraryInfo::location(QLibraryInfo::TranslationsPath));
else
translator2.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
if (!settings->useNoLocale())
app.installTranslator(&translator2);
MainForm window;
window.show();
return app.exec();
}
yagf-0.9.2.1/src/tblock.cpp 0000664 0001750 0001750 00000003000 12250140707 016071 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "tblock.h"
Block::Block(int x, int y, int width, int height) :
QRect(x, y, width, height)
{
number = -1;
language = "default";
}
Block::Block(const QRect &r) : QRect(r.x(), r.y(), r.width(), r.height())
{
number = -1;
}
int Block::blockNumber()
{
return number;
}
void Block::setBlockNumber(const int value)
{
number = value;
}
void Block::setLanguage(const QString &lang)
{
language = lang;
}
QString Block::getLanguage()
{
return language;
}
bool rectLessThan(const QRect &r1, const QRect &r2)
{
if (r1.y() < r2.y())
return true;
if (r1.x() < r2.x())
return true;
return false;
}
void sortBlocks(TBlocks &blocks)
{
qSort(blocks.begin(), blocks.end(), rectLessThan);
}
yagf-0.9.2.1/src/advancedconfigdialog.h 0000664 0001750 0001750 00000002252 12250140707 020403 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef ADVANCEDCONFIGDIALOG_H
#define ADVANCEDCONFIGDIALOG_H
#include
namespace Ui {
class AdvancedConfigDialog;
}
class AdvancedConfigDialog : public QDialog
{
Q_OBJECT
public:
explicit AdvancedConfigDialog(QWidget *parent = 0);
~AdvancedConfigDialog();
bool doCrop1();
void setCrop1(const bool value);
private:
Ui::AdvancedConfigDialog *ui;
};
#endif // ADVANCEDCONFIGDIALOG_H
yagf-0.9.2.1/src/ghostscr.cpp 0000664 0001750 0001750 00000003202 12247205425 016460 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "ghostscr.h"
#include
#include
GhostScr::GhostScr() : PDFExtractor()
{
}
void GhostScr::exec()
{
QString command = "gs";
QStringList args;
args << "-SDEVICE=jpeg" << "-r1200x1200" << "-sPAPERSIZE=letter" << "-dNOPAUSE" << "-dBATCH";
if ((!getStopPage().isEmpty()) || (getStopPage().toInt() > 0)) {
if (getStartPage().toInt() == 0)
this->setStartPage("1");
args << QString("-dFirstPage=").append(getStartPage()) << QString("-dLastPage=").append(getStopPage());
}
if (!getOutputDir().endsWith("/"))
setOutputDir(getOutputDir().append('/'));
setOutputPrefix(getOutputDir().append("page"));
args << QString("-sOutputFile=").append(getOutputPrefix()).append("_%04d.jpg");
args << "--" << this->getSourcePDF();
setOutputExtension("jpg");
execInternal(command, args);
}
yagf-0.9.2.1/src/configdialog.h 0000664 0001750 0001750 00000002342 12247205425 016722 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef CONFIGDIALOG_H
#define CONFIGDIALOG_H
#include
namespace Ui {
class ConfigDialog;
}
class ConfigDialog : public QDialog
{
Q_OBJECT
public:
explicit ConfigDialog(QWidget *parent = 0);
~ConfigDialog();
void setSelectedEngine(int value);
int selectedEngine();
void setTessDataPath(const QString &value); //"" - find yourself
QString tessdataPath();
private:
Ui::ConfigDialog *ui;
};
#endif // CONFIGDIALOG_H
yagf-0.9.2.1/src/utils.h 0000664 0001750 0001750 00000002141 12247205425 015432 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef UTILS_H
#define UTILS_H
class QString;
QString extractFileName(const QString &path);
QString extractFilePath(const QString &path);
QString extractDigits(const QString &fn);
bool findProgram(const QString &name);
inline bool _contains(qreal x1, qreal x2, qreal xc)
{
return ((xc >= x1) && (xc <= x2)) || ((xc <= x1) && (xc >= x2));
}
#endif
yagf-0.9.2.1/src/yagf.qrc 0000775 0001750 0001750 00000004241 12247701361 015564 0 ustar parallels parallels images/rcw.pngimages/rccw.pngimages/revert.pngimages/select.pngimages/smaller.pngimages/larger.pngimages/singlecolumn.pngimages/yagf.pngimages/back.pngimages/document_open.pngimages/document_save_as.pngimages/editcopy.pngimages/filefind.pngimages/fileopen.pngimages/filesaveas.pngimages/forward.pngimages/scanner.pngimages/warning.pngimages/critical.pngimages/info.pngimages/resize.pngimages/resize_block.pngimages/save_all.pngimages/editclear.pngimages/batch.pngimages/remove.pngimages/align.pngimages/undo.pngimages/scanner_s2.pngimages/recblocks.pngimages/trashcan1s.pngimages/trashcan2-s.pngimages/check_spelling.pngimages/savpicas.pngimages/saveblock.pngimages/deskew2.pngimages/stock_new_html.pngimages/application_pdf.pngimages/trashcan_full.pngimages/clearblocks.pngimages/selecttext.pngimages/edit_paste.pngimages/scanner48.pngimages/selectmulti.pngimages/tools_wizard.pngimages/tools_wizard_small.png
yagf-0.9.2.1/src/analysis.h 0000664 0001750 0001750 00000005570 12247205425 016126 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef ANALYSIS_H
#define ANALYSIS_H
#include "ccbuilder.h"
#include
//#include
#include
#include
#include
#include
typedef struct _Rect
{
qint32 x1, x2, y1, y2;
int dotCount;
} Rect;
bool operator==(Rect r1, Rect r2);
typedef QHash ComponentParameters;
typedef QList Strings;
typedef QList StringsBoxes;
typedef QMultiHash GlyphField;
typedef struct ginfo {
ginfo(int a1, int a2, int a3);
int h;
int x;
int y;
} GlyphInfo;
bool operator==(GlyphInfo g1, GlyphInfo g2);
typedef QList TextLine;
typedef QMultiHash LineField;
typedef QList Lines;
typedef QList Bars;
const int BarRatio = 24;
class CCAnalysis : public QObject
{
public:
CCAnalysis(CCBuilder * builder);
~CCAnalysis();
bool analize(bool extractBars = false);
Bars addBars();
TextLine extractLine();
int getGlyphCount();
QList getGlyphs();
int getMediumGlyphHeight();
int getMediumGlyphWidth();
int getMediumLetterSpace();
int getMediumWordSpace();
int getStringsCount();
int getGlyphBoxCount();
Rect getGlyphBox(int index);
QRect getStringBox(const int index) const;
Lines getLines();
qreal getK();
void rotateLines(qreal phi, const QPoint &c = QPoint(0,0));
private:
bool extractComponents(bool extractBars = false);
void classifyGlyphs();
int findAdjacent(Rect &r);
void normalizeLines();
void rotatePhi(qreal phi, const QPoint &c, QPoint &p);
void addBarsHorizontal(int hoffset = 0, int height = -1, int woffset = 0, int width = -1);
void addBarsHorisontalAfterVertical();
void addBarsVertical();
private:
CCBuilder * builder;
ComponentParameters components;
Strings strings;
StringsBoxes boxes;
GlyphField glyphField;
Lines lines;
int glyphCount;
int mediumGlyphHeight;
int mediumGlyphWidth;
int mediumLetterSpace;
int mediumWordSpace;
int stringsCount;
qreal k;
Bars bars;
QVector verts;
};
#endif
yagf-0.9.2.1/src/configdialog.ui 0000664 0001750 0001750 00000007156 12247205425 017120 0 ustar parallels parallels
ConfigDialog00344237OCR Settings:/yagf.png:/yagf.pngOCR Engine12cuneiformtesseractTesseract SetupLocation of the tessdata directory:Qt::Vertical2040Qt::HorizontalQDialogButtonBox::Cancel|QDialogButtonBox::OkbuttonBoxaccepted()ConfigDialogaccept()248254157274buttonBoxrejected()ConfigDialogreject()316260286274
yagf-0.9.2.1/src/forcelocaledialog.h 0000600 0001750 0001750 00000002375 12250171445 017725 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef FORCELOCALEDIALOG_H
#define FORCELOCALEDIALOG_H
#include
namespace Ui {
class ForceLocaleDialog;
}
class ForceLocaleDialog : public QDialog
{
Q_OBJECT
public:
explicit ForceLocaleDialog(QWidget *parent = 0);
~ForceLocaleDialog();
enum Locales {
NoLocale,
RussianLocale,
DefaultLocale
} ;
void setOption(Locales option);
Locales getOption();
private:
Ui::ForceLocaleDialog *ui;
};
#endif // FORCELOCALEDIALOG_H
yagf-0.9.2.1/src/qxttiffiohandler.cpp 0000664 0001750 0001750 00000011603 12247205425 020203 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2012 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "qxttiffiohandler.h"
#include
#include
#include
#include
#include
#include
#include
QXtTiffIOHandler::QXtTiffIOHandler() :
QImageIOHandler()
{
dirnum = 0;
dircount = 0;
tif = NULL;
}
QXtTiffIOHandler::~QXtTiffIOHandler()
{
if (tif)
TIFFClose(tif);
}
static tsize_t readProc(thandle_t handle, tdata_t data, tsize_t size)
{
QIODevice * device = (QIODevice *) handle;
quint32 res = device->read((char *) data, size);
return res;
}
static tsize_t writeProc(thandle_t handle, tdata_t data, tsize_t size)
{
QIODevice * device = (QIODevice *) handle;
quint32 res = device->write((char *) data, size);
return res;
}
static toff_t seekProc(thandle_t handle, toff_t offset, int whence)
{
QIODevice * device = (QIODevice *) handle;
quint64 pos = device->pos();
switch(whence) {
case SEEK_CUR:
pos = pos + offset;
break;
case SEEK_SET :
pos = offset;
break;
case SEEK_END :
pos = device->size() + offset;
break;
default:
break;
}
if (device->seek(pos))
return pos;
return device->pos();
}
static int closeProc(thandle_t handle)
{
QIODevice * device = (QIODevice *) handle;
device->close();
return 0;
}
static toff_t sizeProc(thandle_t handle)
{
QIODevice * device = (QIODevice *) handle;
return device->size();
}
bool QXtTiffIOHandler::canRead() const
{
if (device())
if (device()->isReadable()) {
TIFF * t = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL);
if (t) {
/*dircount = 0;
do {
dircount++;
} while (TIFFReadDirectory(t));*/
device()->reset();
return true;
}
}
return false;
}
bool QXtTiffIOHandler::read(QImage *image)
{
quint32 w;
quint32 h;
char * raster;
tif = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL);
TIFFSetDirectory(tif, dirnum);
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
raster = (char*) _TIFFmalloc(w * h * sizeof (uint32));
QBuffer buff;
if (raster != NULL) {
if (TIFFReadRGBAImage(tif, w, h, (uint32 *)raster, 0)) {
QImage tmp(w, h, QImage::Format_ARGB32);
for (uint32 row = 0; row < h; row++) {
//strncpy((char*)tmp.scanLine(h - row - 1), &raster[4*w*row], 4*w);
quint32 * p = (quint32 *) tmp.scanLine(h - row - 1);
for (quint32 i = 0; i < w; i++)
p[i] = ((quint32 *) raster)[w*row + i];
}
_TIFFfree(raster);
tmp.save(&buff, "JPG");
}
device()->reset();
//TIFFClose(tif);
return image->loadFromData(buff.buffer(), "JPG");
}
return false;
}
QVariant QXtTiffIOHandler::option(QImageIOHandler::ImageOption option) const
{
return QImageIOHandler::option(option);
}
int QXtTiffIOHandler::loopCount() const
{
return 0;
}
int QXtTiffIOHandler::imageCount() //const
{
//device()->open(QIODevice::ReadOnly);
//if (canRead())
{
tif = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL);
dircount = 0;
do {
dircount++;
} while (TIFFReadDirectory(tif));
device()->reset();
//TIFFClose(tif);
return dircount;
}
return dircount;
}
bool QXtTiffIOHandler::jumpToImage(int imageNumber)
{
if (imageNumber < imageCount()) {
dirnum = imageNumber;
return true;
}
return false;
}
bool QXtTiffIOHandler::supportsOption(QImageIOHandler::ImageOption option) const
{
if (option == QImageIOHandler::Animation) return true;
return QImageIOHandler::supportsOption(option);
}
void QXtTiffIOHandler::setOption(QImageIOHandler::ImageOption option, const QVariant &value)
{
QImageIOHandler::setOption(option, value);
}
yagf-0.9.2.1/src/pdf2ppt.h 0000664 0001750 0001750 00000001740 12247205425 015655 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef PDF2PPT_H
#define PDF2PPT_H
#include "pdfextractor.h"
class PDF2PPT : public PDFExtractor
{
public:
PDF2PPT();
virtual void exec();
};
#endif // PDF2PPT_H
yagf-0.9.2.1/src/qgraphicsinput.h 0000664 0001750 0001750 00000006675 12247205425 017353 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef QGRAPHICSINPUT_H
#define QGRAPHICSINPUT_H
#include "sidebar.h"
#include
#include
#include
#include
#include
#include
typedef QList ActionList;
class Block;
class QGraphicsPixmapItem;
class QGraphicsRectItem;
class QPixmap;
class QCursor;
class QRectF;
class QCursor;
class QToolBar;
class QActions;
enum SelectStates {
NoSelect = 0,
StartSelect,
Selecting
};
class QGraphicsInput : public QGraphicsScene
{
Q_OBJECT
public:
explicit QGraphicsInput(const QRectF &sceneRect, QGraphicsView *view = 0);
~QGraphicsInput();
void setView(QGraphicsView *view);
QRect getActiveBlock();
QRect getCurrentBlock();
void deleteBlock(int index);
void deleteCurrentBlock();
void clearBlocks();
bool addBlock(const QRectF &rect, bool removeObstacles = true);
void addBlockColliding(Block block);
void drawLine(int x1, int y1, int x2, int y2);
void imageOrigin(QPoint &p);
QPixmap getCurrentImage();
void cropWhiteFrame();
void setMagnifierCursor(QCursor *cursor);
void addToolBarAction(QAction * action);
void addToolBarSeparator();
void setToolBarVisible();
QGraphicsRectItem *newBlock(const QRectF &rect);
bool loadImage(const QPixmap &pixmap);
//setMagnifierCursor(QCursor * cursor = );
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);
virtual void wheelEvent(QGraphicsSceneWheelEvent *wheelEvent);
virtual void keyReleaseEvent(QKeyEvent *keyEvent);
virtual void keyPressEvent(QKeyEvent *keyEvent);
signals:
void leftMouseClicked(int x, int y, bool blockSelected);
void rightMouseClicked(int x, int y, bool inTheBlock);
void keyPressed(int key);
void increaseMe();
void decreaseMe();
void blockCreated(QRect rect);
void deleteBlock(QRect rect);
private slots:
private:
void leftMouseRelease(qreal x, qreal y);
void rightMouseRelease(qreal x, qreal y);
int nearActiveBorder(qreal x, qreal y);
void clearTransform();
void addToolBar();
void deleteBlockRect(QGraphicsRectItem *item);
QGraphicsView *m_view;
QGraphicsPixmapItem *m_image;
QGraphicsRectItem *m_CurrentBlockRect;
QGraphicsRectItem *m_LastSelected;
SelectStates selecting;
QRectF blockRect;
QRectF selBlockRect;
bool hasImage;
Qt::MouseButton buttonPressed;
QCursor *magnifierCursor;
int near_res;
QPointer toolbar;
ActionList actionList;
QRect redRect;
bool xred;
};
#endif // QGRAPHICSINPUT_H
yagf-0.9.2.1/src/scanner.cpp 0000664 0001750 0001750 00000006333 12250140707 016260 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "scanner.h"
#include "utils.h"
#include
class XSaneScannerFE : public ScannerBase
{
public:
XSaneScannerFE(const QString &PLL, QObject *parent = 0) : ScannerBase(parent)
{
addParameter("-s");
addParameter("-n");
addParameter("-N");
setProgramName("XSane");
setPreloadLibrary(PLL);
addEnvironmentVar("LD_PRELOAD=" + PLL);
}
void exec()
{
waitFor();
execInternal("xsane");
}
};
ScannerBase::ScannerBase(QObject *parent) :
QObject(parent), scanProcess(this)
{
environment.append(QProcess::systemEnvironment());
}
ScannerBase::~ScannerBase()
{
waitFor();
}
void ScannerBase::addParameter(const QString &s)
{
parameters.append(s);
}
void ScannerBase::addEnvironmentVar(const QString &s)
{
environment.append(s);
}
void ScannerBase::setOutputFile(const QString &s)
{
outputFile = s;
}
QString ScannerBase::programName()
{
return pName;
}
void ScannerBase::waitFor()
{
scanProcess.terminate();
scanProcess.waitForFinished(10000);
}
void ScannerBase::execInternal(const QString &s)
{
scanProcess.setEnvironment(environment);
QStringList sl;
sl.append(parameters);
sl.append(outputFile);
connect(&scanProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)));
scanProcess.start(s, sl);
}
void ScannerBase::setProgramName(const QString &s)
{
pName = s;
}
void ScannerBase::setPreloadLibrary(const QString &s)
{
preloadLibrary = s;
}
QString ScannerFactory::findPreloadLibrary()
{
QFileInfo lib;
lib.setFile("/usr/local/lib/yagf/libxspreload.so");
if (!lib.exists()) {
lib.setFile("/usr/lib/yagf/libxspreload.so");
if (!lib.exists()) {
lib.setFile("/usr/lib64/yagf/libxspreload.so");
if (!lib.exists())
lib.setFile("/usr/local/lib64/yagf/libxspreload.so");
}
}
if (lib.exists())
return lib.filePath();
else return "";
}
void ScannerFactory::findFEs()
{
if (findProgram("xsane"))
fes << "xsane";
}
ScannerFactory::ScannerFactory()
{
preloadPath = findPreloadLibrary();
findFEs();
}
ScannerBase *ScannerFactory::createScannerFE(const QString &name)
{
if (fes.contains(name))
return new XSaneScannerFE(preloadPath);
return NULL;
}
void ScannerBase::finished(int, QProcess::ExitStatus)
{
emit processFinished();
}
yagf-0.9.2.1/src/PageAnalysis.h 0000664 0001750 0001750 00000003076 12247205425 016662 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef PAGEANALYSIS_H
#define PAGEANALYSIS_H
#include
#include
#include
#include
#include
#include "ycommon.h"
#include "analysis.h"
class QPixmap;
class QImage;
class QRect;
class BlockSplitter
{
public:
void setImage(const QImage &image, qreal rotation, qreal scale);
QRect getRootBlock(const QImage &image);
Bars getBars(); // call after something calls blockAllText();
void splitBlocks();
QRect getRotationCropRect(const QImage &image);
QList getBlocks();
private:
QRect blockAllText();
void splitVertical();
void splitHorisontal();
bool isBlockRecogniseable(const Rect &block);
private:
QImage img;
qreal m_rotate;
qreal m_scale;
int generalBr;
Bars bars;
Lines lines;
QList blocks;
};
#endif
yagf-0.9.2.1/src/mainform.cpp 0000775 0001750 0001750 00000106217 12250140750 016442 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "sidebar.h"
#include "droplabel.h"
#include "popplerdialog.h"
#include "pdfextractor.h"
#include "pdf2ppt.h"
#include "ghostscr.h"
#include "configdialog.h"
#include "advancedconfigdialog.h"
#include "mainform.h"
#include "tpagecollection.h"
#include "scanner.h"
#include "projectmanager.h"
#include "forcelocaledialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "qgraphicsinput.h"
#include "utils.h"
#include "qxtunixsignalcatcher.h"
#include "PageAnalysis.h"
#include
#include
#include
#include
#include
const QString outputBase = "output";
const QString outputExt = ".txt";
const QString inputFile = "input.bmp";
const QString outputFile = "output.txt";
const QString scanOutputFile = "input.png";
MainForm::MainForm(QWidget *parent): QMainWindow(parent)
{
setupUi(this);
pages = PageCollection::instance();
setWindowTitle("YAGF");
//spellChecker = new SpellChecker(textEdit);
textEdit->enumerateDicts();
frame->show();
//toolBar->addWidget(label1);
//toolBar->addWidget(selectLangsBox);
graphicsInput = new QGraphicsInput(QRectF(0, 0, 2000, 2000), graphicsView) ;
graphicsInput->addToolBarAction(actionHideShowTolbar);
graphicsInput->addToolBarAction(this->actionTBLV);
graphicsInput->addToolBarAction(this->actionSmaller_view);
graphicsInput->addToolBarSeparator();
graphicsInput->addToolBarAction(actionRotate_90_CCW);
graphicsInput->addToolBarAction(actionRotate_180);
graphicsInput->addToolBarAction(actionRotate_90_CW);
graphicsInput->addToolBarAction(actionPrepare_Page);
graphicsInput->addToolBarAction(actionDeskew);
graphicsInput->addToolBarSeparator();
graphicsInput->addToolBarAction(actionSelect_Text_Area);
graphicsInput->addToolBarAction(actionSelect_multiple_blocks);
graphicsInput->addToolBarAction(ActionClearAllBlocks);
label->setListWidget(sideBar);
connect(sideBar, SIGNAL(pageSelected(int)), pages, SLOT(pageSelected(int)));
connect(label, SIGNAL(pageRemoved(int)), pages, SLOT(pageRemoved(int)));
statusBar()->show();
useXSane = TRUE;
scanner = NULL;
//rotation = 0;
m_menu = new QMenu(graphicsView);
ifCounter = 0;
connect(actionOpen, SIGNAL(triggered()), this, SLOT(loadImage()));
connect(actionQuit, SIGNAL(triggered()), this, SLOT(close()));
connect(this, SIGNAL(windowShown()), this, SLOT(onShowWindow()), Qt::QueuedConnection);
connect(actionScan, SIGNAL(triggered()), this, SLOT(scanImage()));
connect(actionPreviousPage, SIGNAL(triggered()), this, SLOT(loadPreviousPage()));
connect(actionNextPage, SIGNAL(triggered()), this, SLOT(loadNextPage()));
connect(actionRecognize, SIGNAL(triggered()), this, SLOT(recognize()));
connect(action_Save, SIGNAL(triggered()), textEdit, SLOT(saveText()));
connect(actionAbout, SIGNAL(triggered()), this, SLOT(showAboutDlg()));
connect(actionOnlineHelp, SIGNAL(triggered()), this, SLOT(showHelp()));
connect(actionCopyToClipboard, SIGNAL(triggered()),textEdit, SLOT(copyClipboard()));
connect(graphicsInput, SIGNAL(rightMouseClicked(int, int, bool)), this, SLOT(rightMouseClicked(int, int, bool)));
connect(actionSelect_HTML_format, SIGNAL(triggered()), this, SLOT(selectHTMLformat()));
connect(graphicsInput, SIGNAL(increaseMe()), this, SLOT(enlargeButtonClicked()));
connect(graphicsInput, SIGNAL(decreaseMe()), this, SLOT(decreaseButtonClicked()));
connect(sideBar, SIGNAL(filesDropped(QStringList)), SLOT(loadFiles(QStringList)));
connect(pages, SIGNAL(loadPage()), this, SLOT(loadPage()));
connect(graphicsInput, SIGNAL(blockCreated(QRect)), pages, SLOT(addBlock(QRect)));
connect(graphicsInput, SIGNAL(deleteBlock(QRect)), pages, SLOT(deleteBlock(QRect)));
connect(sideBar, SIGNAL(fileRemoved(int)), pages, SLOT(pageRemoved(int)));
connect (pages, SIGNAL(addSnippet(int)), this, SLOT(addSnippet(int)));
selectLangsBox = new QComboBox();
selectLangsBox->setToolTip(trUtf8("Recognition language"));
toolBar->insertWidget(actionRecognize, selectLangsBox);
// connect(selectLangsBox->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(LangTextChanged(QString)));
initSettings();
engineLabel = new QLabel();
statusBar()->addPermanentWidget(engineLabel, 0);
if (settings->getSelectedEngine() == UseCuneiform) {
//fillLanguagesBoxCuneiform();
engineLabel->setText(trUtf8("Using Cuneiform"));
}
if (settings->getSelectedEngine() == UseTesseract) {
//fillLanguagesBoxTesseract();
engineLabel->setText(trUtf8("Using Tesseract"));
}
fillLangBox();
delTmpFiles();
QXtUnixSignalCatcher::connectUnixSignal(SIGUSR2);
ba = new QByteArray();
connect(QXtUnixSignalCatcher::catcher(), SIGNAL(unixSignal(int)), this, SLOT(readyRead(int)));
QPixmap l_cursor;
l_cursor.load(":/resize.png");
resizeCursor = new QCursor(l_cursor);
graphicsInput->setMagnifierCursor(resizeCursor);
l_cursor.load(":/resize_block.png");
resizeBlockCursor = new QCursor(l_cursor);
// textEdit->setContextMenuPolicy(Qt::ActionsContextMenu);
this->sideBar->show();
//connect(sideBar, SIGNAL(fileSelected(const QString &)), this, SLOT(fileSelected(const QString &)));
connect(actionRecognize_All_Pages, SIGNAL(triggered()), this, SLOT(recognizeAll()));
QPixmap pm;
pm.load(":/align.png");
//alignButton->setIcon(pm);
pm.load(":/undo.png");
//unalignButton->setIcon(pm);
//connect(unalignButton, SIGNAL(clicked()), this, SLOT(unalignButtonClicked()));
//clearBlocksButton->setDefaultAction(ActionClearAllBlocks);
loadFromCommandLine();
emit windowShown();
pdfx = NULL;
if (findProgram("pdftoppm")) {
pdfx = new PDF2PPT();
} else
if (findProgram("gs")) {
pdfx = new GhostScr();
}
if (pdfx) {
connect(pdfx, SIGNAL(addPage(QString)), this, SLOT(addPDFPage(QString)), Qt::QueuedConnection);
connect (pdfx, SIGNAL(finished()), this, SLOT(finishedPDF()));
}
pdfPD.setWindowTitle("YAGF");
pdfPD.setLabelText(trUtf8("Importing pages from the PDF document..."));
pdfPD.setCancelButtonText(trUtf8("Cancel"));
pdfPD.setMinimum(-1);
pdfPD.setMaximum(-1);
pdfPD.setWindowIcon(QIcon(":/yagf.png"));
if (pdfx)
connect(&pdfPD, SIGNAL(canceled()), pdfx, SLOT(cancel()));
menu_Settings->addAction("UI Language", this, SLOT(setUILanguage()));
}
void MainForm::onShowWindow()
{
// actionCheck_spelling->setCheckable(true);
connect(selectLangsBox, SIGNAL(currentIndexChanged(int)), this, SLOT(newLanguageSelected(int)));
selectLangsBox->setCurrentIndex(selectLangsBox->findData(QVariant(settings->getLanguage())));
//spellChecker->setLanguage(language);
//actionCheck_spelling->setEnabled(spellChecker->spellCheck());
}
void MainForm::loadFromCommandLine()
{
QStringList sl = QApplication::arguments();
if (sl.count() > 1) {
if (QFile::exists(sl.at(1)))
loadFile(sl.at(1));
for (int i = 2; i < sl.count(); i++) {
QApplication::processEvents();
if (QFile::exists(sl.at(i)))
loadFile(sl.at(i));
}
sideBar->select(sl.at(1));
}
}
void MainForm::loadFiles(QStringList files)
{
for (int i = 0; i < files.count(); i++)
if (QFile::exists(files.at(i)))
loadFile(files.at(i));
}
void MainForm::LangTextChanged(const QString &text)
{
if (selectLangsBox->findText(text, Qt::MatchStartsWith) < 0)
selectLangsBox->lineEdit()->setText("");
}
void MainForm::showConfigDlg()
{
ConfigDialog dialog(this);
SelectedEngine ose = settings->getSelectedEngine();
if (settings->getSelectedEngine() == UseCuneiform)
dialog.setSelectedEngine(0);
else
dialog.setSelectedEngine(1);
dialog.setTessDataPath(settings->getTessdataPath());
if (dialog.exec()) {
settings->setSelectedEngine(dialog.selectedEngine() == 0 ? UseCuneiform : UseTesseract);
settings->setTessdataPath(dialog.tessdataPath());
if (settings->getSelectedEngine() != ose) {
QString oldLang = selectLangsBox->currentText();
selectLangsBox->clear();
if (settings->getSelectedEngine() == UseCuneiform) {
engineLabel->setText(trUtf8("Using Cuneiform"));
}
if (settings->getSelectedEngine() == UseTesseract) {
engineLabel->setText(trUtf8("Using Tesseract"));
}
fillLangBox();
int newIndex = selectLangsBox->findText(oldLang);
if (newIndex >= 0) {
selectLangsBox->setCurrentIndex(newIndex);
settings->setLanguage(selectLangsBox->itemData(newIndex).toString());
} else {
settings->setLanguage("eng");
for (int i = 0; i < selectLangsBox->count(); i++) {
QString s = selectLangsBox->itemData(i).toString();
if (s == "eng") {
newLanguageSelected(i);
selectLangsBox->setCurrentIndex(i);
break;
}
}
}
}
}
}
void MainForm::importPDF()
{
if (!pdfx) {
QMessageBox::critical(this, trUtf8("No PDF converter installed"), trUtf8("No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required)."));
return;
}
PopplerDialog dialog(this);
if (dialog.exec()) {
pdfx->setSourcePDF(dialog.getPDFFile());
if (pdfx->getSourcePDF().isEmpty()) {
QMessageBox::information(this, trUtf8("Error"), trUtf8("PDF file name may not be empty"));
return;
}
pdfx->setStartPage(dialog.getStartPage());
pdfx->setStopPage(dialog.getStopPage());
bool doit = true;
QString outputDir;
while (doit) {
outputDir = QFileDialog::getExistingDirectory(this, trUtf8("Select an existing directory for output or create some new one")); //, QString(""), QString(), (QString*) NULL, QFileDialog::ShowDirsOnly);
if (outputDir.isEmpty())
return;
QDir dir(outputDir);
if (dir.count() > 2)
QMessageBox::warning(this, trUtf8("Selecting Directory"), trUtf8("The selected directory is not empty"));
else doit = false;
}
pdfx->setOutputDir(outputDir);
QApplication::processEvents();
pdfPD.setWindowFlags(Qt::Dialog|Qt::WindowStaysOnTopHint);
pdfPD.show();
pdfPD.setMinimum(0);
pdfPD.setMaximum(100);
QApplication::processEvents();
pdfx->exec();
}
}
void MainForm::addPDFPage(QString pageName)
{
pages->appendPage(pageName);
pdfPD.setValue(pdfPD.value()+1);
}
void MainForm::finishedPDF()
{
pdfPD.hide();
}
void MainForm::loadImage()
{
QFileDialog dialog(this,
trUtf8("Open Image"), settings->getLastDir(), trUtf8("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)"));
dialog.setFileMode(QFileDialog::ExistingFiles);
if (dialog.exec()) {
QStringList fileNames;
fileNames = dialog.selectedFiles();
settings->setLastDir(dialog.directory().path());
if (fileNames.count() > 0)
loadFile(fileNames.at(0), true);
if (!pages->pageValid())
return;
for (int i = 1; i < fileNames.count(); i++) {
loadFile(fileNames.at(i), false);
}
// if (fileNames.count() > 0)
// pages->makePageCurrent(0);
}
}
void MainForm::singleColumnButtonClicked()
{
//singleColumn = singleColumnButton->isChecked();
}
void MainForm::closeEvent(QCloseEvent *event)
{
if (!textEdit->textSaved()) {
QPixmap icon;
icon.load(":/info.png");
QMessageBox messageBox(QMessageBox::NoIcon, "YAGF", trUtf8("There is an unsaved text in the editor window. Do you want to save it?"),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, this);
messageBox.setIconPixmap(icon);
int result = messageBox.exec();
if (result == QMessageBox::Save)
textEdit->saveText();
else if (result == QMessageBox::Cancel) {
event->ignore();
return;
}
}
if (scanner) {
delete scanner;
scanner = NULL;
}
settings->setSize(size());
settings->setPosition(pos());
settings->setFullScreen(isFullScreen());
settings->writeSettings();
delTmpFiles();
event->accept();
QXtUnixSignalCatcher::catcher()->disconnectUnixSugnals();
pages->clear();
}
void MainForm::rotateCWButtonClicked()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
pages->rotate90CW();
setCursor(oldCursor);
}
void MainForm::rotateCCWButtonClicked()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
pages->rotate90CCW();
setCursor(oldCursor);
}
void MainForm::rotate180ButtonClicked()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
pages->rotate180();
setCursor(oldCursor);
}
void MainForm::enlargeButtonClicked()
{
pages->makeLarger();
}
void MainForm::decreaseButtonClicked()
{
pages->makeSmaller();
}
void MainForm::initSettings()
{
settings = Settings::instance();
if (settings->getFullScreen())
showFullScreen();
else {
move(settings->getPosition());
resize(settings->getSize());
}
actionCheck_spelling->setChecked(settings->getCheckSpelling());
actionSelect_HTML_format->setChecked(settings->getOutputFormat() != "text");
QList li;
li.append(1);
li.append(1);
splitter->setSizes(li);
toolBar->setIconSize(settings->getIconSize());
}
void MainForm::newLanguageSelected(int index)
{
settings->setLanguage(selectLangsBox->itemData(index).toString());
actionCheck_spelling->setEnabled(textEdit->hasDict(settings->getLanguage()));
if (settings->getCheckSpelling()) {
settings->setCheckSpelling(textEdit->spellCheck(settings->getLanguage()));
//actionCheck_spelling->setEnabled(checkSpelling);
actionCheck_spelling->setChecked(settings->getCheckSpelling());
}
}
void MainForm::scanImage()
{
if (useXSane) {
if (scanner) {
delete scanner;
}
ScannerFactory * sf = new ScannerFactory();
scanner = sf->createScannerFE("xsane");
if (scanner == NULL) {
QMessageBox::warning(this, trUtf8("Scanning is impossible"), trUtf8("No scanning front-end is found. Please install XSane in order to perform scanning."));
return;
}
scanner->setOutputFile(settings->workingDir() + scanOutputFile);
delete sf;
scanner->exec();
}
}
void MainForm::loadFile(const QString &fn, bool loadIntoView)
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
if (pages->appendPage(fn)) {
if (loadIntoView) {
pages->makePageCurrent(pages->count()-1);
loadPage();
sideBar->item(sideBar->count()-1)->setSelected(true);
}
} else {
QMessageBox::warning(this, trUtf8("Failed to Load Image"), fn);
}
setCursor(oldCursor);
}
void MainForm::delTmpFiles()
{
QDir dir(settings->workingDir());
dir.setFilter(QDir::Files | QDir::NoSymLinks);
for (uint i = 0; i < dir.count(); i++) {
if (dir[i].endsWith("jpg") || dir[i].endsWith("bmp") || dir[i].endsWith("png") || dir[i].endsWith("txt"))
dir.remove(dir[i]);
}
delTmpDir();
}
void MainForm::loadNextPage()
{
}
void MainForm::loadPreviousPage()
{
}
// TODO: think on blocks/page recognition
bool MainForm::useTesseract(const QString &inputFile)
{
QProcess proc;
proc.setWorkingDirectory(settings->workingDir());
QStringList sl;
sl.append(inputFile);
sl.append(outputBase);
sl.append("-l");
sl.append(settings->getLanguage());
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("TESSDATA_PREFIX", settings->getTessdataPath());
proc.setProcessEnvironment(env);
proc.start("tesseract", sl);
proc.waitForFinished(-1);
if (proc.exitCode()) {
QByteArray stdout = proc.readAllStandardOutput();
QByteArray stderr = proc.readAllStandardError();
QString output = QString(stdout) + QString(stderr);
QMessageBox::critical(this, trUtf8("Starting tesseract failed"), trUtf8("The system said: ") + (output != "" ? output : trUtf8("program not found")));
return false;
}
return true;
}
bool MainForm::useCuneiform(const QString &inputFile, const QString &outputFile)
{
QProcess proc;
proc.setWorkingDirectory(settings->workingDir());
QStringList sl;
sl.append("-l");
sl.append(settings->getLanguage());
sl.append("-f");
if (settings->getOutputFormat() == "text")
sl.append("text");
else
sl.append("html");
sl.append("-o");
sl.append(settings->workingDir() + outputFile);
sl.append(settings->workingDir() + inputFile);
proc.start("cuneiform", sl);
proc.waitForFinished(-1);
if (proc.exitCode()) {
QByteArray stdout = proc.readAllStandardOutput();
QByteArray stderr = proc.readAllStandardError();
QString output = QString(stdout) + QString(stderr);
QMessageBox::critical(this, trUtf8("Starting cuneiform failed"), trUtf8("The system said: ") + (output != "" ? output : trUtf8("program not found")));
return false;
}
return true;
}
void MainForm::recognizeInternal()
{
if (settings->getSelectedEngine() == UseCuneiform) {
if (!useCuneiform(inputFile, outputFile))
return;
}
if (settings->getSelectedEngine() == UseTesseract) {
if (!useTesseract(inputFile))
return;
}
QFile textFile(settings->workingDir() + outputFile);
textFile.open(QIODevice::ReadOnly);
QByteArray text = textFile.readAll();
textFile.close();
QString textData;
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
textData = codec->toUnicode(text); //QString::fromUtf8(text.data());
if (settings->getOutputFormat() == "text")
textData.prepend("");
textData.replace("", "\"--");
textData.replace(".bmp>", "");
// textData.replace("-
", "");
// textData.replace("- ", "");
textEdit->append(textData);
textEdit->append(QString(" "));
if (settings->getCheckSpelling()) {
actionCheck_spelling->setChecked(textEdit->spellCheck(settings->getLanguage()));
}
}
void MainForm::recognize()
{
QFile::remove(settings->workingDir() + "input*.bmp");
if (!pages->pageValid()) {
QMessageBox::critical(this, trUtf8("Error"), trUtf8("No image loaded"));
return;
}
if (!findEngine()) return;
if (pages->blockCount() > 0) {
for (int i = 0; i < pages->blockCount(); i++) {
prepareBlockForRecognition(i);
recognizeInternal();
}
} else {
preparePageForRecognition();
recognizeInternal();
}
}
void MainForm::showAboutDlg()
{
QPixmap icon;
icon.load(":/yagf.png");
QMessageBox aboutBox(QMessageBox::NoIcon, trUtf8("About YAGF"), trUtf8("
YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines
Version %1
Ⓒ 2009-2013 Andrei Borovsky
This is a free software distributed under GPL v3. Visit http://symmetrica.net/cuneiform-linux/yagf-en.html for more details.").arg(version), QMessageBox::Ok);
aboutBox.setIconPixmap(icon);
QList labels = aboutBox.findChildren();
for (int i = 0; i < labels.count(); i++) {
QLabel *lab = labels.at(i);
lab->setTextInteractionFlags(Qt::TextBrowserInteraction);
}
aboutBox.setTextFormat(Qt::RichText);
aboutBox.exec();
}
void MainForm::showHelp()
{
QDesktopServices::openUrl(QUrl(trUtf8("http://symmetrica.net/cuneiform-linux/yagf-en.html")));
}
void MainForm::readyRead(int sig)
{
QFile f(settings->workingDir() + scanOutputFile);
QString newName = QString(settings->workingDir() + "scan-input-%1.png").arg(ifCounter);
ifCounter++;
QFileInfo fi(newName);
if (fi.exists()) {
QFile f2(newName);
f2.remove();
}
f.rename(newName);
loadFile(newName);
}
void MainForm::delTmpDir()
{
QDir dir;
dir.setPath(settings->workingDir() + "output_files");
dir.setFilter(QDir::Files | QDir::NoSymLinks);
for (uint i = 0; i < dir.count(); i++) {
if (dir[i].endsWith("jpg") || dir[i].endsWith("bmp"))
dir.remove(dir[i]);
}
dir.rmdir(settings->workingDir() + "output_files");
}
void MainForm::clearTmpFiles()
{
QFile::remove(settings->workingDir() + "tmp*.bmp");
QFile f(settings->workingDir()+inputFile);
f.remove();
f.setFileName(settings->workingDir()+outputFile);
f.remove();
}
void MainForm::fillLangBox()
{
settings->startLangPair();
QString full;
QString abbr;
selectLangsBox->clear();
while(settings->getLangPair(full, abbr))
selectLangsBox->addItem(full, QVariant(abbr));
}
void MainForm::preparePageForRecognition()
{
clearTmpFiles();
pages->savePageForRecognition(settings->workingDir() + inputFile);
}
void MainForm::prepareBlockForRecognition(const QRect &r)
{
clearTmpFiles();
pages->saveBlockForRecognition(r, settings->workingDir() + inputFile);
}
void MainForm::prepareBlockForRecognition(int index)
{
clearTmpFiles();
pages->saveBlockForRecognition(index, settings->workingDir() + inputFile);
}
void MainForm::setResizingCusor()
{
//scrollArea->widget()->setCursor(*resizeBlockCursor);
}
void MainForm::setUnresizingCusor()
{
//scrollArea->widget()->setCursor(QCursor(Qt::ArrowCursor));
}
void MainForm::loadPage()
{
//graphicsInput->clearBlocks();
graphicsInput->loadImage(pages->pixmap());
QApplication::processEvents();
for (int i = 0; i < pages->blockCount(); i++)
graphicsInput->addBlockColliding(pages->getBlock(i));
QFileInfo fi(pages->fileName());
setWindowTitle(QString("YAGF - %1").arg(fi.fileName()) );
}
void MainForm::recognizeAll()
{
if (pages->count() == 0)
return;
QProgressDialog progress(trUtf8("Recognizing pages..."), trUtf8("Abort"), 0, pages->count(), this);
progress.setWindowTitle("YAGF");
progress.show();
progress.setValue(0);
pages->makePageCurrent(-1);
for (int i = 0; i < pages->count(); i++) {
progress.setValue(i);
if (progress.wasCanceled())
break;
pages->makeNextPageCurrent();
recognize();
}
}
void MainForm::unalignButtonClicked()
{
/*if (((QSelectionLabel *) scrollArea->widget())->pixmap()->isNull())
return;
int rot = ((FileToolBar *) m_toolBar)->getRotation();
int rrot = ((rot + 45)/90);
rrot *=90;
rotateImage(rrot - rot);
rotation = rrot;*/
}
void MainForm::hideToolBar()
{
graphicsInput->setToolBarVisible();
}
void MainForm::on_ActionClearAllBlocks_activated()
{
pages->clearBlocks();
loadPage();
}
void MainForm::rightMouseClicked(int x, int y, bool inTheBlock)
{
m_menu->clear();
m_menu->addAction(ActionClearAllBlocks);
if (inTheBlock) {
m_menu->addAction(ActionDeleteBlock);
m_menu->addAction(actionRecognize_block);
m_menu->addAction(actionSave_block);
m_menu->addAction(actionDeskew_by_Block);
} else {
m_menu->addAction(actionSelect_Text_Area);
m_menu->addAction(actionSelect_multiple_blocks);
}
QPoint p = graphicsView->mapToGlobal(QPoint(x, y));
m_menu->move(p);
m_menu->show();
}
void MainForm::on_ActionDeleteBlock_activated()
{
QRect r = graphicsInput->getCurrentBlock();
graphicsInput->deleteCurrentBlock();
pages->deleteBlock(r);
}
bool MainForm::findEngine() {
if (settings->getSelectedEngine() == UseCuneiform) {
if (!findProgram("cuneiform")) {
if (findProgram("tesseract")) {
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("cuneiform not found, switching to tesseract"));
settings->setSelectedEngine(UseTesseract);
} else {
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("No recognition engine found.\nPlease install either cuneiform or tesseract"));
return false;
}
}
}
if (settings->getSelectedEngine() == UseTesseract) {
if (!findProgram("tesseract")) {
if (findProgram("cuneiform")) {
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("tesseract not found, switching to cuneiform"));
settings->setSelectedEngine(UseCuneiform);
} else {
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("No recognition engine found.\nPlease install either cuneiform or tesseract"));
return false;
}
}
}
return true;
}
void MainForm::on_actionRecognize_block_activated()
{
if (!findEngine()) return;
if (graphicsInput->getCurrentBlock().isNull())
return;
clearTmpFiles();
pages->saveRawBlockForRecognition(graphicsInput->getCurrentBlock(), settings->workingDir() + inputFile);
recognizeInternal();
}
/*void MainForm::on_actionRecognize_activated()
{
}*/
void MainForm::on_actionCheck_spelling_triggered()
{
settings->setCheckSpelling(actionCheck_spelling->isChecked());
}
void MainForm::on_actionSave_current_image_activated()
{
QCursor oc = cursor();
setCursor(Qt::WaitCursor);
QString format;
QString fn = getFileNameToSaveImage(format);
if (!fn.isEmpty()) {
if (!(pages->savePageAsImage(fn, format)))
QMessageBox::warning(this, QObject::trUtf8("Warning"), QObject::trUtf8("Failed to save the image"));
}
setCursor(oc);
}
QString MainForm::getFileNameToSaveImage(QString &format)
{
QString jpegFilter = QObject::trUtf8("JPEG Files (*.jpg)");
QString pngFilter = QObject::trUtf8("PNG Files (*.png)");
QStringList filters;
format = "JPEG";
filters << jpegFilter << pngFilter;
QFileDialog dialog(this,
trUtf8("Save Image"), settings->getLastOutputDir());
dialog.setFilters(filters);
dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setDefaultSuffix("jpg");
if (dialog.exec()) {
if (dialog.selectedNameFilter() == jpegFilter) {
format = "JPEG";
dialog.setDefaultSuffix("jpg");
} else if (dialog.selectedNameFilter() == pngFilter) {
format = "PNG";
dialog.setDefaultSuffix("png");
}
QStringList fileNames;
fileNames = dialog.selectedFiles();
settings->setLastOutputDir(dialog.directory().path());
return fileNames.at(0);
}
return "";
}
MainForm::~MainForm()
{
delete resizeBlockCursor;
delete resizeCursor;
//delete fileChannel;
delete graphicsInput;
delete ba;
delete pdfx;
}
void MainForm::on_actionSave_block_activated()
{
QString format;
QString fn = getFileNameToSaveImage(format);
if (!fn.isEmpty())
pages->saveBlockForRecognition(graphicsInput->getCurrentBlock(), fn, format);
}
void MainForm::on_actionCheck_spelling_activated()
{
settings->setCheckSpelling(actionCheck_spelling->isChecked());
if (settings->getCheckSpelling()) {
actionCheck_spelling->setChecked(textEdit->spellCheck(settings->getLanguage()));
} else
textEdit->unSpellCheck();
}
/*void MainForm::on_alignButton_clicked()
{
this->AnalizePage();
}*/
void MainForm::on_actionDeskew_activated()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
pages->deskew();
setCursor(oldCursor);
}
void MainForm::on_actionSelect_HTML_format_activated()
{
if (actionSelect_HTML_format->isChecked())
settings->setOutputFormat("html");
else
settings->setOutputFormat("text");
}
void MainForm::pasteimage()
{
QClipboard *clipboard = QApplication::clipboard();
QPixmap pm = clipboard->pixmap();
if (pm.isNull()) return;
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
QString tmpFile = "input-01.png";
QFileInfo fi(settings->workingDir() + tmpFile);
while (fi.exists()) {
QString digits = extractDigits(tmpFile);
bool result;
int d = digits.toInt(&result);
if (!result) return;
d++;
if (d < 0) d = 0;
QString newDigits = QString::number(d);
while (newDigits.size() < digits.size())
newDigits = '0' + newDigits;
tmpFile = tmpFile.replace(digits, newDigits);
fi.setFile(settings->workingDir(), tmpFile);
}
pm.save(fi.absoluteFilePath(), "PNG");
loadFile(fi.absoluteFilePath());
setCursor(oldCursor);
}
void MainForm::deskewByBlock()
{
/*QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
graphicsInput->update();
QApplication::processEvents();
if (!graphicsInput->getCurrentBlock().isNull()) {
QImage img = graphicsInput->getCurrentBlock();*/
pages->deskew();
//}
///setCursor(oldCursor);
}
void MainForm::selectTextArea()
{
pages->blockAllText();
}
void MainForm::showAdvancedSettings()
{
AdvancedConfigDialog dlg;
dlg.setCrop1(settings->getCropLoaded());
if (dlg.exec()) {
settings->setCropLoaded(dlg.doCrop1());
}
}
void MainForm::addSnippet(int index)
{
sideBar->addItem((QListWidgetItem *) pages->snippet());
}
void MainForm::preprocessPage()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
if (!pages->splitPage(true))
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to detect text areas on this page.\nThe page possibly lacks contrast. Try to select blocks manually."));
setCursor(oldCursor);
}
void MainForm::saveProject()
{
if (settings->getProjectDir().isEmpty()) {
QString dir = QFileDialog::getExistingDirectory(this, QObject::trUtf8("Select Project Directory"), "");
if (dir.isEmpty())
return;
QCursor oldCursor = cursor();
QDir dinfo(dir);
if (dinfo.entryList().count() > 2) {
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("The selected directoy is not empty. Please select or create another one."));
} else {
ProjectSaver ps;
if (!ps.save(dir))
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to save the project."));
else
settings->setProjectDir(dir);
}
setCursor(oldCursor);
} else {
QCursor oldCursor = cursor();
ProjectSaver ps;
if (!ps.save(settings->getProjectDir()))
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to save the project."));
setCursor(oldCursor);
}
}
void MainForm::loadProject()
{
pages->clear();
QString dir = QFileDialog::getExistingDirectory(this, QObject::trUtf8("Select Project Directory"), "");
if (dir.isEmpty())
return;
QCursor oldCursor = cursor();
ProjectLoader pl;
if (!pl.load(dir))
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to load project."));
else
settings->setProjectDir(dir);
setCursor(oldCursor);
}
void MainForm::selectBlocks()
{
QCursor oldCursor = cursor();
setCursor(Qt::WaitCursor);
if (!pages->splitPage(false))
QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to detect text areas on this page.\nThe page possibly lacks contrast. Try to select blocks manually."));
setCursor(oldCursor);
}
void MainForm::setSmallIcons()
{
QSize s = toolBar->iconSize();
if (s.height() > 32) {
s.setHeight(32);
s.setWidth(32);
}
else {
s.setHeight(48);
s.setWidth(48);
}
toolBar->setIconSize(s);
settings->setIconSize(s);
}
void MainForm::selectHTMLformat()
{
if (actionSelect_HTML_format->isChecked())
settings->setOutputFormat("html");
else
settings->setOutputFormat("text");
}
void MainForm::setUILanguage()
{
ForceLocaleDialog fld(this);
if (settings->useNoLocale())
fld.setOption(ForceLocaleDialog::NoLocale);
else {
if (settings->useRussianLocale())
fld.setOption(ForceLocaleDialog::RussianLocale);
else {
fld.setOption(ForceLocaleDialog::DefaultLocale);
}
}
if (fld.exec() == QDialog::Accepted) {
settings->setNoLocale(false);
settings->setRussianLocale(false);
if (fld.getOption() == ForceLocaleDialog::NoLocale)
settings->setNoLocale(true);
else {
if (fld.getOption() == ForceLocaleDialog::RussianLocale)
settings->setRussianLocale(true);
}
}
}
yagf-0.9.2.1/src/PageAnalysis.cpp 0000664 0001750 0001750 00000016451 12247205425 017216 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "PageAnalysis.h"
#include "CCAnalysis.h"
#include "ccbuilder.h"
#include "analysis.h"
#include "utils.h"
#include
#include
#include
#include
#include
void BlockSplitter::setImage(const QImage &image, qreal rotation, qreal scale)
{
img = image;
m_rotate = rotation;
m_scale = scale;
}
QRect BlockSplitter::getRootBlock(const QImage &image)
{
if (image.isNull())
return QRect(0,0,0,0);
QImage img1 = image;
QRect result = blockAllText();
RotationCropper rc(&img1, QColor("white").rgb(), generalBr);
CCBuilder cb(img1);
//img1.save("/home/anre/pictures/ttt.png");
QRect r = cb.crop();//rc.crop();
QRect r1(result.x() + r.x(), result.y() + r.y(), result.width(), result.height());
result = r1;
foreach (Rect rc, bars) {
bars.removeOne(rc);
rc.x1 += r.x();
rc.x2 += r.x();
rc.y1 += r.y();
rc.y2 += r.y();
bars.append(rc);
}
return result;
}
Bars BlockSplitter::getBars()
{
return bars;
}
QRect BlockSplitter::blockAllText()
{
//img = img.transformed(QTransform().translate(-x, -y).rotate(m_rotate).translate(x, y), Qt::SmoothTransformation);
if (!img.isNull()) {
CCBuilder * cb = new CCBuilder(img);
cb->setGeneralBrightness(360);
cb->setMaximumColorComponent(100);
cb->labelCCs();
CCAnalysis * an = new CCAnalysis(cb);
an->analize();
lines = an->getLines();
foreach(TextLine l, lines)
if (l.count() < 3)
lines.removeOne(l);
int minX = 100000;
int minY = 100000;
int maxX = 0;
int maxY = 0;
for (int i =0; i < lines.count(); i++) {
int x1 = lines.at(i).at(0).x;
int y1 = lines.at(i).at(0).y;
int x2 = lines.at(i).at(lines.at(i).count()-1).x;
int y2 = lines.at(i).at(lines.at(i).count()-1).y;
//graphicsInput->drawLine(x1,y1,x2,y2);
if (x1 > x2) {
int t = x2;
x2 = x1;
x1 = t;
}
minX = minX < x1 ? minX : x1;
maxX = maxX > x2 ? maxX : x2;
if (y1 > y2) {
int t = y2;
y2 = y1;
y1 = t;
}
minY = minY < y1 ? minY : y1;
maxY = maxY > y2 ? maxY : y2;
}
minX = minX - 2*an->getMediumGlyphWidth();
maxX =maxX + 2*an->getMediumGlyphWidth();
minY = minY - 2*an->getMediumGlyphHeight();
maxY = maxY + 2*an->getMediumGlyphHeight();
//graphicsInput->clearBlocks();
//graphicsInput->addBlock(QRectF(ox + minX*2*sideBar->getScale(), oy + minY*2*sideBar->getScale(), (maxX-minX)*2*sideBar->getScale(), (maxY-minY)*2*sideBar->getScale()));
bars = an->addBars();
delete an;
generalBr = cb->getGB();
delete cb;
minX = minX <= 0 ? 1 :minX;
minY = minY <= 0 ? 1 :minY;
return QRect(minX*2*m_scale, minY*2*m_scale, (maxX-minX)*2*m_scale, (maxY-minY)*2*m_scale);
}
return QRect(0, 0, 0, 0);
}
void BlockSplitter::splitVertical()
{
bool didSplit = true;
while(didSplit) {
didSplit = false;
for (int i = blocks.count() - 1; i >=0; i--) {
Rect block = blocks.at(i);
foreach(Rect bar, bars) {
if (abs(bar.x2 - bar.x1) > (bar.y2-bar.y1))
continue;
int xmid = (bar.x1 + bar.x2)/2;
if ((block.x1 < (xmid - 5)) &&(block.x2 > (xmid + 5))) {
Rect block1 = block;
block1.x2 = xmid -2;
Rect block2 = block;
block2.x1 = xmid + 2;
blocks.removeAll(block);
blocks.append(block1);
blocks.append(block2);
didSplit = true;
break;
}
}
}
}
}
void BlockSplitter::splitBlocks()
{
QRect r = getRootBlock(img);
Rect b;
b.x1 = r.x();
b.y1 = r.y();
b.x2 = b.x1 + r.width();
b.y2 = b.y1 + r.height();
blocks.clear();
blocks.append(b);
splitVertical();
splitHorisontal();
// qSort(blocks.begin(), blocks.end(), rectLessThan);
for (int i = blocks.count() -1; i >=0; i--) {
Rect r = blocks.at(i);
if (!isBlockRecogniseable(r))
blocks.removeAll(r);
}
}
QList BlockSplitter::getBlocks()
{
return blocks;
}
QRect BlockSplitter::getRotationCropRect(const QImage &image)
{
const QImage * img = ℑ
QImage * img2 = const_cast(img);
RotationCropper rc(img2, QColor("white").rgb(), generalBr);
return rc.crop();
}
void BlockSplitter::splitHorisontal()
{
bool didSplit = true;
while(didSplit) {
didSplit = false;
for (int i = blocks.count() - 1; i >=0; i--) {
Rect block = blocks.at(i);
foreach(Rect bar, bars) {
if (abs(bar.y2 - bar.y1) > (bar.x2-bar.x1))
continue;
int ymid = (bar.y1 + bar.y2)/2;
if ((block.y1 < (ymid - 5)) &&(block.y2 > (ymid + 5)))
if (_contains(bar.x1, bar.x2, block.x1)||_contains(bar.x1, bar.x2, block.x2)||_contains(block.x1, block.x2, bar.x1)||_contains(block.x1, block.x2, bar.x2)) {
Rect block1 = block;
block1.y2 = ymid -2;
Rect block2 = block;
block2.y1 = ymid + 2;
blocks.removeAll(block);
blocks.append(block1);
blocks.append(block2);
didSplit = true;
break;
}
}
}
}
}
inline bool between(int a, int b, int c)
{
return (c > a) && (c < b);
}
bool BlockSplitter::isBlockRecogniseable(const Rect &block)
{
int contains = 0;
int maxl = 0;
foreach(TextLine l, lines) {
if (!between(block.x1, block.x2, l.first().x))
continue;
if (!between(block.x1, block.x2, l.last().x))
continue;
if (!between(block.y1, block.y2, l.first().y))
continue;
if (!between(block.y1, block.y2, l.last().y))
continue;
contains++;
if (l.count() > maxl) maxl = l.count();
}
if ((maxl > 3)) return true;
return false;
}
yagf-0.9.2.1/src/texteditor.cpp 0000664 0001750 0001750 00000017550 12250140707 017025 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "texteditor.h"
#include "settings.h"
#include "ycommon.h"
#include "utils.h"
#include
#include
#include
#include
#include
#include
#include
#include
TextEditor::TextEditor(QWidget *parent) :
QTextEdit(parent), spellChecker(this)
{
hasCopy = false;
mTextSaved = true;
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(document(), SIGNAL(cursorPositionChanged(const QTextCursor &)), this, SLOT(updateSP()));
connect(this, SIGNAL(copyAvailable(bool)), this, SLOT(copyAvailable(bool)));
connect(this, SIGNAL(textChanged()), this, SLOT(textChanged()));
}
TextEditor::~TextEditor()
{
}
bool TextEditor::textSaved()
{
return mTextSaved;
}
bool TextEditor::spellCheck(const QString &lang)
{
spellChecker.setLanguage(lang);
return spellChecker.spellCheck();
}
void TextEditor::unSpellCheck()
{
spellChecker.unSpellCheck();
}
void TextEditor::enumerateDicts()
{
spellChecker.enumerateDicts();
}
bool TextEditor::hasDict(const QString &shname)
{
return spellChecker.hasDict(shname);
}
void TextEditor::saveText()
{
Settings * settings = Settings::instance();
QString filter;
if (settings->getOutputFormat() == "text")
filter = trUtf8("Text Files (*.txt)");
else
filter = trUtf8("HTML Files (*.html)");
QFileDialog dialog(this,
trUtf8("Save Text"), settings->getLastOutputDir(), filter);
if (settings->getOutputFormat() == "text")
dialog.setDefaultSuffix("txt");
else
dialog.setDefaultSuffix("html");
dialog.setAcceptMode(QFileDialog::AcceptSave);
if (dialog.exec()) {
QStringList fileNames;
fileNames = dialog.selectedFiles();
settings->setLastOutputDir(dialog.directory().path());
QFile textFile(fileNames.at(0));
textFile.open(QIODevice::ReadWrite | QIODevice::Truncate);
if (settings->getOutputFormat() == "text")
textFile.write(toPlainText().toUtf8());
else
saveHtml(&textFile);
textFile.close();
mTextSaved = true;
}
}
void TextEditor::keyPressEvent(QKeyEvent *e)
{
if (e->modifiers() & Qt::ControlModifier) {
if ((e->key() == Qt::Key_Plus) || (e->key() == Qt::Key_Equal)) {
enlargeFont();
e->accept();
return;
} else if (e->key() == Qt::Key_Minus) {
decreaseFont();
e->accept();
return;
}
}
QTextEdit::keyPressEvent(e);
}
void TextEditor::wheelEvent(QWheelEvent *e)
{
if (e->modifiers() & Qt::ControlModifier) {
if (e->delta() > 0)
enlargeFont();
else
decreaseFont();
e->accept();
return;
}
QTextEdit::wheelEvent(e);
}
void TextEditor::replaceWord()
{
QAction * action = (QAction *) sender();
QTextCursor cursor = textCursor();
cursor.select(QTextCursor::WordUnderCursor);
cursor.removeSelectedText();
cursor.insertText(action->text());
}
void TextEditor::copyAvailable(bool yes)
{
hasCopy = yes;
}
void TextEditor::textChanged()
{
mTextSaved = !(toPlainText().count());
Settings * settings = Settings::instance();
QFont f(font());
f.setPointSize(settings->getFontSize());
setFont(f);
}
void TextEditor::copyClipboard()
{
if (!hasCopy) {
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(toPlainText(), QClipboard::Clipboard);
} else
copy();
}
void TextEditor::saveHtml(QFile *file)
{
QString text = document()->toHtml().toUtf8();
QString newDir = extractFilePath(file->fileName()) + extractFileName(file->fileName()) + ".files";
text.replace("", "");
/*text.replace(workingDir + "output_files", newDir);
text.replace("[img src=", "");
text.replace(".bmp]", ".bmp>");
QDir dir(workingDir+"output_files");
dir.rename(workingDir+"output_files", newDir);*/
file->write(text.toAscii());
}
void TextEditor::contextMenuRequested(const QPoint &point)
{
QAction *action;
QMenu * menu = new QMenu(this);
QStringList sl = spellChecker.suggestions();
//if (sl.count() == 0) {
action = new QAction(trUtf8("Undo\tCtrl+Z"), this);
action->setShortcut(QKeySequence("Ctrl+Z"));
connect(action, SIGNAL(triggered()), this, SLOT(undo()));
menu->addAction(action);
action = new QAction(trUtf8("Redo\tCtrl+Shift+Z"), this);
action->setShortcut(QKeySequence("Ctrl+Shift+Z"));
connect(action, SIGNAL(triggered()), this, SLOT(redo()));
menu->addAction(action);
action = new QAction("separator", this);
action->setText("");
action->setSeparator(true);
menu->addAction(action);
action = new QAction(trUtf8("Select All\tCtrl+A"), this);
action->setShortcut(QKeySequence("Ctrl+A"));
connect(action, SIGNAL(triggered()), this, SLOT(selectAll()));
menu->addAction(action);
action = new QAction(trUtf8("Cut\tCtrl+X"), this);
action->setShortcut(QKeySequence("Ctrl+X"));
connect(action, SIGNAL(triggered()), this, SLOT(cut()));
menu->addAction(action);
action = new QAction(trUtf8("Copy\tCtrl+C"), this);
action->setShortcut(QKeySequence("Ctrl+C"));
connect(action, SIGNAL(triggered()), this, SLOT(copyClipboard()));
menu->addAction(action);
action = new QAction(trUtf8("Paste\tCtrl+V"), this);
action->setShortcut(QKeySequence("Ctrl+V"));
connect(action, SIGNAL(triggered()), this, SLOT(paste()));
menu->addAction(action);
action = new QAction("separator", this);
action->setText("");
action->setSeparator(true);
menu->addAction(action);
action = new QAction(trUtf8("Larger Font\tCtrl++"), this);
connect(action, SIGNAL(triggered()), this, SLOT(enlargeFont()));
menu->addAction(action);
action = new QAction(trUtf8("Smaller Font\tCtrl+-"), this);
connect(action, SIGNAL(triggered()), this, SLOT(decreaseFont()));
menu->addAction(action);
//}
if (sl.count() > 0)
menu->addSeparator();
foreach(QString str, sl) {
QAction * action = menu->addAction(str);
connect(action, SIGNAL(triggered()), this, SLOT(replaceWord()));
}
menu->exec(mapToGlobal(point));
delete menu;
}
void TextEditor::enlargeFont()
{
Settings * settings = Settings::instance();
int fontSize = font().pointSize();
fontSize++;
QFont f(font());
f.setPointSize(fontSize);
setFont(f);
settings->setFontSize(fontSize);
}
void TextEditor::decreaseFont()
{
Settings * settings = Settings::instance();
int fontSize = font().pointSize();
if (fontSize > 1) fontSize--;
QFont f(font());
f.setPointSize(fontSize);
setFont(f);
settings->setFontSize(fontSize);
}
void TextEditor::updateSP()
{
Settings * settings = Settings::instance();
if (settings->getCheckSpelling())
spellChecker.checkWord();
}
yagf-0.9.2.1/src/CCAnalysis.h 0000664 0001750 0001750 00000002705 12250140707 016264 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef CCANALYSIS_H
#define CCANALYSIS_H
#include
#include
#include "ycommon.h"
class QImage;
class RotationCropper
{
public:
RotationCropper(QImage * image, QRgb color, int dtr);
~RotationCropper();
QRect crop();
private:
void recolor();
bool checkHorzLine(int y);
bool checkVertLine(int x);
private:
QImage * image;
QRgb whitePixel;
QRgb replaceColor;
int darksCount;
int lightsCount;
int minval;
int maxval;
//int clAltCount;
int whitesCount;
int darktr;
int whitetr;
int whiteAlt;
qreal clBrighttoWidth;
qreal clBrighttoWidthtr;
int clWhiteCount;
int y1, y2, x1, x2;
};
#endif
yagf-0.9.2.1/src/settings.cpp 0000664 0001750 0001750 00000032674 12250171073 016476 0 ustar parallels parallels /*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "settings.h"
#include "utils.h"
#include
#include
#include
#include
Settings * Settings::m_instance = NULL;
Settings::Settings()
{
//makeLanguageMaps();
}
Settings::Settings(const Settings &)
{
}
Settings::~Settings()
{
}
Settings *Settings::instance()
{
if (!m_instance)
m_instance = new Settings();
return m_instance;
}
void Settings::readSettings(const QString &path)
{
mPath = path;
mPath = mPath.append("yagf.ini");
settings = new QSettings(mPath, QSettings::IniFormat);
lastDir = settings->value("mainwindow/lastDir").toString();
lastOutputDir = settings->value("mainwindow/lastOutputDir").toString();
QString defEngine;
if (findProgram("tesseract")&&(!findProgram("cuneiform")))
defEngine = "tesseract";
else
defEngine = "cuneiform";
QString engine = settings->value("ocr/engine", QVariant(defEngine)).toString();
if (engine == "cuneiform")
selectedEngine = UseCuneiform;
else
selectedEngine = UseTesseract;
language = settings->value("ocr/language", selectDefaultLanguageName()).toString();
//selectLangsBox->setCurrentIndex(selectLangsBox->findData(QVariant(language)));
outputFormat = settings->value("ocr/outputFormat", QString("text")).toString();
if (outputFormat == "") outputFormat = "text";
checkSpelling = settings->value("mainWindow/checkSpelling", bool(true)).toBool();
bool ok;
fontSize = settings->value("mainwindow/fontSize", int(12)).toInt(&ok);
noLocale = settings->value("mainwindow/nolocale", QVariant(false)).toBool();
RussianLocale = settings->value("mainwindow/rulocale", QVariant(false)).toBool();
findTessDataPath();
tessdataPath = settings->value("ocr/tessData", QVariant(tessdataPath)).toString();
if (tessdataPath.isEmpty())
findTessDataPath();
cropLoaded = settings->value("processing/crop1", QVariant(true)).toBool();
size = settings->value("mainwindow/size", QSize(800, 600)).toSize();
iconSize = settings->value("mainwindow/iconSize", QSize(48, 48)).toSize();
position = settings->value("mainwindow/pos", QPoint(0, 0)).toPoint();
fullScreen = settings->value("mainwindow/fullScreen", QVariant(false)).toBool();
}
void Settings::writeSettings()
{
settings->setValue("mainwindow/size", size);
settings->setValue("mainwindow/iconSize", iconSize);
settings->setValue("mainwindow/pos", position);
settings->setValue("mainwindow/fullScreen", fullScreen);
settings->setValue("mainwindow/lastDir", lastDir);
settings->setValue("mainWindow/checkSpelling", checkSpelling);
settings->setValue("mainwindow/lastOutputDir", lastOutputDir);
settings->setValue("mainwindow/fontSize", fontSize);
settings->setValue("mainwindow/nolocale", noLocale);
settings->setValue("mainwindow/rulocale", RussianLocale);
settings->setValue("ocr/language", language);
//settings->setValue("ocr/singleColumn", singleColumn);
settings->setValue("ocr/outputFormat", outputFormat);
QString engine = selectedEngine == UseCuneiform ? QString("cuneiform") : QString("tesseract");
settings->setValue("ocr/engine", engine);
settings->setValue("ocr/tessData", tessdataPath);
settings->setValue("processing/crop1", cropLoaded);
settings->sync();
}
QString Settings::getLanguage()
{
return language;
}
QString Settings::getOutputFormat()
{
return outputFormat;
}
QString Settings::getLastDir()
{
return lastDir;
}
QString Settings::getLastOutputDir()
{
return lastOutputDir;
}
bool Settings::getCheckSpelling()
{
return checkSpelling;
}
QString Settings::getTessdataPath()
{
if (!tessdataPath.endsWith("/"))
tessdataPath = tessdataPath.append("/");
return tessdataPath;
}
SelectedEngine Settings::getSelectedEngine()
{
return selectedEngine;
}
QSize Settings::getSize()
{
return size;
}
QPoint Settings::getPosition()
{
return position;
}
bool Settings::getFullScreen()
{
return fullScreen;
}
int Settings::getFontSize()
{
return fontSize;
}
bool Settings::getCropLoaded()
{
return cropLoaded;
}
void Settings::setLanguage(const QString &value)
{
language = value;
}
void Settings::setOutputFormat(const QString &value)
{
outputFormat = value;
}
void Settings::setLastDir(const QString &value)
{
lastDir = value;
}
void Settings::setLastOutputDir(const QString &value)
{
lastOutputDir = value;
}
void Settings::setCheckSpelling(const bool value)
{
checkSpelling = value;
}
void Settings::setTessdataPath(const QString &value)
{
tessdataPath = value;
}
void Settings::setSelectedEngine(const SelectedEngine value)
{
selectedEngine = value;
}
void Settings::setSize(const QSize &value)
{
size = value;
}
void Settings::setPosition(const QPoint &value)
{
position = value;
}
void Settings::setFullScreen(const bool value)
{
fullScreen = value;
}
void Settings::setFontSize(const int &value)
{
fontSize = value;
}
void Settings::setCropLoaded(const bool value)
{
cropLoaded = value;
}
QString Settings::workingDir()
{
QString wDir = QDir::homePath();
if (!wDir.endsWith("/"))
wDir += '/';
QDir d(wDir + ".config");
if (d.exists()) wDir += ".config/";
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
wDir = env.value("XDG_CONFIG_HOME", wDir);
if (!wDir.endsWith("/"))
wDir += '/';
wDir += "yagf/";
QDir dir(wDir);
if (!dir.exists())
dir.mkdir(wDir);
return wDir;
}
void Settings::startLangPair()
{
lpi = 0;
}
bool Settings::getLangPair(QString &full, QString &abbr)
{
QMap * map;
if (selectedEngine == UseCuneiform)
map = &cuMap;
if (selectedEngine == UseTesseract)
map = &tesMap;
full = map->keys().at(lpi);
abbr = map->value(full);
lpi++;
if (lpi < map->count())
return true;
return false;
}
void Settings::setProjectDir(const QString &dir)
{
projectDir = dir;
}
QString Settings::getProjectDir()
{
return projectDir;
}
void Settings::makeLanguageMaps()
{
cuMap.insert(QObject::trUtf8("Bulgarian"), "bul");
cuMap.insert(QObject::trUtf8("Czech"), "cze");
cuMap.insert(QObject::trUtf8("Danish"), "dan");
cuMap.insert(QObject::trUtf8("Dutch"), "dut");
cuMap.insert(QObject::trUtf8("English"), "eng");
cuMap.insert(QObject::trUtf8("French"), "fra");
cuMap.insert(QObject::trUtf8("German"), "ger");
cuMap.insert(QObject::trUtf8("Hungarian"), "hun");
cuMap.insert(QObject::trUtf8("Italian"), "ita");
cuMap.insert(QObject::trUtf8("Latvian"), "lav");
cuMap.insert(QObject::trUtf8("Lithuanian"), "lit");
cuMap.insert(QObject::trUtf8("Polish"), "pol");
cuMap.insert(QObject::trUtf8("Portuguese"), "por");
cuMap.insert(QObject::trUtf8("Romanian"), "rum");
cuMap.insert(QObject::trUtf8("Russian"), "rus");
cuMap.insert(QObject::trUtf8("Russian-English"), "ruseng");
cuMap.insert(QObject::trUtf8("Spanish"), "spa");
cuMap.insert(QObject::trUtf8("Serbian"), "srp");
cuMap.insert(QObject::trUtf8("Slovenian"), "slo");
cuMap.insert(QObject::trUtf8("Swedish"), "swe");
cuMap.insert(QObject::trUtf8("Ukrainian"), "ukr");
tesMap.insert(QObject::trUtf8("Bulgarian"), "bul");
tesMap.insert(QObject::trUtf8("Czech"), "ces");
tesMap.insert(QObject::trUtf8("Danish"), "dan");
tesMap.insert(QObject::trUtf8("Dutch"), "nld");
tesMap.insert(QObject::trUtf8("English"), "eng");
tesMap.insert(QObject::trUtf8("Finnish"), "fin");
tesMap.insert(QObject::trUtf8("French"), "fra");
tesMap.insert(QObject::trUtf8("German"), "deu");
tesMap.insert(QObject::trUtf8("German Gothic"), "gerf");
tesMap.insert(QObject::trUtf8("Greek"), "ell");
tesMap.insert(QObject::trUtf8("Hebrew"), "heb");
tesMap.insert(QObject::trUtf8("Hungarian"), "hun");
tesMap.insert(QObject::trUtf8("Italian"), "ita");
tesMap.insert(QObject::trUtf8("Latvian"), "lav");
tesMap.insert(QObject::trUtf8("Lithuanian"), "lit");
tesMap.insert(QObject::trUtf8("Norwegian"), "nor");
tesMap.insert(QObject::trUtf8("Polish"), "pol");
tesMap.insert(QObject::trUtf8("Portuguese"), "por");
tesMap.insert(QObject::trUtf8("Romanian"), "ron");
tesMap.insert(QObject::trUtf8("Russian"), "rus");
tesMap.insert(QObject::trUtf8("Serbian"), "srp");
tesMap.insert(QObject::trUtf8("Slovenian"), "slv");
tesMap.insert(QObject::trUtf8("Slovak"), "slk");
tesMap.insert(QObject::trUtf8("Spanish"), "spa");
tesMap.insert(QObject::trUtf8("Swedish"), "swe");
tesMap.insert(QObject::trUtf8("Swedish Gothic"), "swef");
tesMap.insert(QObject::trUtf8("Turkish"), "tur");
tesMap.insert(QObject::trUtf8("Ukrainian"), "ukr");
}
void Settings::findTessDataPath()
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
if (env.contains("TESSDATA_PREFIX")) {
tessdataPath = env.value("TESSDATA_PREFIX");
return;
}
QDir dir;
dir.setPath("/usr/share/tessdata");
if (dir.exists()) {
tessdataPath = "/usr/share/";
return;
}
dir.setPath("/usr/local/share/tessdata");
if (dir.exists()) {
tessdataPath = "/usr/local/share/";
return;
}
dir.setPath("/usr/local/share/tesseract-ocr/tessdata");
if (dir.exists()) {
tessdataPath = "/usr/local/share/tesseract-ocr/";
return;
}
dir.setPath("/usr/share/tesseract-ocr/tessdata");
if (dir.exists()) {
tessdataPath = "/usr/share/tesseract-ocr/";
return;
}
tessdataPath.clear();
return;
}
QString Settings::selectDefaultLanguageName()
{
QLocale loc = QLocale::system();
QString name = "";
QMap * map;
if (selectedEngine == UseCuneiform)
map = &cuMap;
if (selectedEngine == UseTesseract)
map = &tesMap;
switch (loc.language()) {
case QLocale::Bulgarian:
name = map->value("Bulgarian");
break;
case QLocale::Czech:
name = map->value("Czech");
break;
case QLocale::Danish:
name = map->value("Danish");
break;
case QLocale::German:
name = map->value("German");
break;
case QLocale::Dutch:
name = map->value("Dutch");
break;
case QLocale::Russian:
name = map->value("Russian");
break;
case QLocale::English:
name = "eng";
break;
case QLocale::Spanish:
name = map->value("Spanish");
break;
case QLocale::French:
name = map->value("French");
break;
case QLocale::Hungarian:
name = map->value("Hungarian");
break;
case QLocale::Italian:
name = map->value("Italian");
break;
case QLocale::Latvian:
name = map->value("Latvian");
break;
case QLocale::Lithuanian:
name = map->value("Lithuanian");
break;
case QLocale::Polish:
name = map->value("Polish");
break;
case QLocale::Portuguese:
name = map->value("Portuguese");
break;
case QLocale::Romanian:
name = map->value("Romanian");
break;
case QLocale::Swedish:
name = map->value("Swedish");
break;
case QLocale::Serbian:
name = map->value("Serbian");
break;
case QLocale::Slovenian:
name = map->value("Slovenian");
break;
case QLocale::Slovak:
name = map->value("Slovak", "eng");
break;
case QLocale::Ukrainian:
name = map->value("Ukrainian");
break;
case QLocale::Finnish:
name = map->value("Finnish", "eng");
break;
case QLocale::Greek:
name = map->value("Greek", "eng");
break;
case QLocale::Hebrew:
name = map->value("Hebrew", "eng");
break;
case QLocale::Norwegian:
name = map->value("Norwegian", "eng");
break;
case QLocale::Turkish:
name = map->value("Turkish", "eng");
break;
default:
break;
}
if (name == "")
name = "eng";
return name;
}
QSize Settings::getIconSize()
{
return iconSize;
}
void Settings::setIconSize(const QSize &value)
{
iconSize = value;
}
bool Settings::useNoLocale()
{
return noLocale;
}
bool Settings::useRussianLocale()
{
return RussianLocale;
}
void Settings::setNoLocale(bool value)
{
noLocale = value;
}
void Settings::setRussianLocale(bool value)
{
RussianLocale = value;
}
yagf-0.9.2.1/src/qgraphicsinput.cpp 0000664 0001750 0001750 00000041544 12247205425 017700 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "qgraphicsinput.h"
#include "qxtgraphicsview.h"
#include "qxtgraphicsproxywidget.h"
#include "ccbuilder.h"
#include "analysis.h"
#include "PageAnalysis.h"
#include "math.h"
#include "ycommon.h"
#include "tblock.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
QGraphicsInput::QGraphicsInput(const QRectF &sceneRect, QGraphicsView *view) :
QGraphicsScene(sceneRect)
{
setView(view);
m_image = 0;
selecting = NoSelect;
hasImage = false;
m_LastSelected = 0;
buttonPressed = Qt::NoButton;
near_res = 0;
magnifierCursor = new QCursor(Qt::SizeAllCursor);
toolbar = 0;
redRect.setX(0);
redRect.setY(0);
redRect.setWidth(0);
redRect.setHeight(0);
xred = false;
}
QGraphicsInput::~QGraphicsInput()
{
delete magnifierCursor;
}
void QGraphicsInput::addToolBar()
{
toolbar = new QToolBar(m_view);
toolbar->setMouseTracking(false);
toolbar->setMovable(false);
toolbar->setWindowOpacity(0.75);
toolbar->move(0,0);
toolbar->setIconSize(QSize(24,24));
toolbar->setMinimumHeight(32);
//toolbar->setCursor();
actionList.at(0)->setText(QString::fromUtf8(">>"));
setToolBarVisible();
//QXtGraphicsProxyWidget * pw = new QXtGraphicsProxyWidget();
//pw->setWidget(toolbar);
//pw->setZValue(100);
//this->addItem(pw);
//pw->setView((QXtGraphicsView *) views().at(0));
//toolbar->setParent(0);
toolbar->show();
foreach (QAction * action, actionList) {
toolbar->addAction(action);
}
((QXtGraphicsView *) views().at(0))->sendScrollSignal();
}
bool QGraphicsInput::loadImage(const QPixmap &pixmap)
{
clear();
m_LastSelected = 0;
m_CurrentBlockRect = 0;
// clearBlocks();
m_image = addPixmap(pixmap);
setSceneRect(pixmap.rect());
m_image->setZValue(-1);
QApplication::processEvents();
//m_realImage->setData(1, "image");
//m_realImage->hide();
this->setFocus();
m_image->setFocus();
m_image->setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MidButton);
m_image->setAcceptHoverEvents(true);
m_image->setData(1, "image");
addToolBar();
if (m_view) {
m_view->centerOn(0, 0);
m_view->show();
update();
hasImage = true;
return true;
} else
return false;
}
void QGraphicsInput::setView(QGraphicsView *view)
{
m_view = view;
if (m_view)
m_view->setScene(this);
}
void QGraphicsInput::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsScene::mousePressEvent(event);
// QMessageBox::critical(0, "MOUS111", "MOUSE");
if (!hasImage)
return;
if (event->buttons() == Qt::LeftButton) {
buttonPressed = Qt::LeftButton;
if (selecting == NoSelect) {
if ((near_res = nearActiveBorder(event->scenePos().x(), event->scenePos().y())) != 0) {
m_CurrentBlockRect = m_LastSelected;
selecting = Selecting;
blockRect = m_CurrentBlockRect->rect();
} else {
selecting = StartSelect;
blockRect.setLeft(event->lastScenePos().x());
blockRect.setTop(event->lastScenePos().y());
blockRect.setWidth(10);
blockRect.setHeight(10);
}
} else {
//TODO!!!
}
} else
buttonPressed = Qt::RightButton;
}
void QGraphicsInput::deleteBlockRect(QGraphicsRectItem *item)
{
if (item == 0)
return;
if (item == m_CurrentBlockRect)
m_CurrentBlockRect = 0;
if (item == m_LastSelected)
m_LastSelected = 0;
removeItem(item);
}
void QGraphicsInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseReleaseEvent(mouseEvent);
if (buttonPressed == Qt::LeftButton) {
if (selecting == Selecting) {
selecting = NoSelect;
if ((blockRect.width() < 12) || (blockRect.height() < 12)) {
if (m_CurrentBlockRect == m_LastSelected)
m_LastSelected = 0;
deleteBlockRect(m_CurrentBlockRect);
//clik!!!
leftMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y());
}
else emit blockCreated(QRectF2Rect(m_CurrentBlockRect->rect()));
if (xred)
emit deleteBlock(redRect);
xred = false;
m_CurrentBlockRect = 0;
}
if (selecting == StartSelect) {
selecting = NoSelect;
m_CurrentBlockRect = 0;
leftMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y());
}
}
if (buttonPressed == Qt::RightButton) {
this->rightMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y());
}
buttonPressed = Qt::NoButton;
}
QGraphicsRectItem *QGraphicsInput::newBlock(const QRectF &rect)
{
QPen p(Qt::SolidLine);
QBrush b(Qt::SolidPattern);
b.setColor(QColor(0, 0, 127, 127));
p.setWidth(2);
p.setColor(QColor(0, 0, 255));
QGraphicsRectItem *res;
res = this->addRect(rect, p, b);
res->setAcceptHoverEvents(true);
res->setZValue(1);
res->setData(1, "block");
res->setData(2, "no");
return res;
}
bool QGraphicsInput::addBlock(const QRectF &rect, bool removeObstacles)
{
QGraphicsRectItem *block = newBlock(rect);
if (!removeObstacles) {
if (block->collidingItems().size() > 0) {
deleteBlockRect(block);
return false;
}
} else {
for (int i = block->collidingItems().size() - 1; i >= 0; i--) {
if (block->collidingItems().at(i)->data(1) == "block")
deleteBlockRect((QGraphicsRectItem *) block->collidingItems().at(i));
}
}
m_CurrentBlockRect = block;
return true;
}
void QGraphicsInput::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseMoveEvent(mouseEvent);
if (selecting == StartSelect) {
selecting = Selecting;
m_CurrentBlockRect = newBlock(blockRect);
}
if ((mouseEvent->modifiers() & Qt::ControlModifier) == 0)
if (mouseEvent->buttons() == Qt::NoButton) {
near_res = nearActiveBorder(mouseEvent->scenePos().x(), mouseEvent->scenePos().y());
switch (near_res) {
case 0:
m_view->viewport()->setCursor(Qt::ArrowCursor);
break;
case 1:
m_view->viewport()->setCursor(Qt::SplitHCursor);
break;
case 2:
m_view->viewport()->setCursor(Qt::SplitVCursor);
break;
case 3:
m_view->viewport()->setCursor(Qt::SplitHCursor);
break;
case 4:
m_view->viewport()->setCursor(Qt::SplitVCursor);
break;
default:
break;
}
}
QRectF newRect;
if (near_res && (mouseEvent->buttons()&Qt::LeftButton)) {
if (!xred)
redRect = QRectF2Rect(m_LastSelected->rect());
xred = true;
QRectF newRect = m_LastSelected->mapRectToScene(m_LastSelected->rect());
switch (near_res) {
case 1:
newRect.setLeft(mouseEvent->lastScenePos().x());
break;
case 2:
newRect.setTop(mouseEvent->lastScenePos().y());
break;
case 3:
newRect.setRight(mouseEvent->lastScenePos().x());
break;
case 4:
newRect.setBottom(mouseEvent->lastScenePos().y());
break;
default:
break;
}
m_CurrentBlockRect = m_LastSelected;
m_CurrentBlockRect->setRect(m_LastSelected->mapRectFromScene(newRect));
for (int i = 0; i < m_CurrentBlockRect->collidingItems().size(); ++i)
if (m_CurrentBlockRect->collidingItems().at(i)->data(1) == "block") {
m_CurrentBlockRect->setRect(m_LastSelected->mapRectFromScene(selBlockRect));
return;
}
selBlockRect = newRect;
return;
}
if (selecting == Selecting) {
newRect = blockRect;
if (newRect.left() < mouseEvent->lastScenePos().x())
newRect.setRight(mouseEvent->lastScenePos().x());
else
newRect.setLeft(mouseEvent->lastScenePos().x());
if (newRect.top() < mouseEvent->lastScenePos().y())
newRect.setBottom(mouseEvent->lastScenePos().y());
else
newRect.setTop(mouseEvent->lastScenePos().y());
m_CurrentBlockRect->setRect(newRect);
for (int i = 0; i < m_CurrentBlockRect->collidingItems().size(); ++i)
if (m_CurrentBlockRect->collidingItems().at(i)->data(1) == "block") {
m_CurrentBlockRect->setRect(blockRect);
return;
}
blockRect = newRect;
return;
}
if (!toolbar.isNull()) {
// if (mouseEvent->pos().y() < toolbar->height())
// toolbar->setFocus();
}
}
void QGraphicsInput::leftMouseRelease(qreal x, qreal y)
{
QGraphicsItem *it = this->itemAt(x, y);
if (it) {
if (it->data(1).toString() == "block") {
QGraphicsRectItem *r = (QGraphicsRectItem *) it;
QPen p(Qt::SolidLine);
QBrush b(Qt::SolidPattern);
b.setColor(QColor(0, 0, 127, 127));
p.setColor(QColor(0, 0, 255));
p.setWidth(2);
if (r->data(2).toString() == "no") {
//select block!!!!
if (m_LastSelected) {
m_LastSelected->setPen(p);
m_LastSelected->setBrush(b);
m_LastSelected->setData(2, "no");
}
b.setColor(QColor(127, 0, 0, 127));
p.setColor(QColor(255, 0, 0));
r->setData(2, "yes");
m_LastSelected = r;
selBlockRect = m_LastSelected->rect();
redRect = QRectF2Rect(selBlockRect); // ATT
// emit addBlock(QRectF2Rect(selBlockRect));
} else {
m_LastSelected = 0;
r->setData(2, "no");
}
r->setPen(p);
r->setBrush(b);
// m_CurrentBlockRect = r;
}
} else
m_CurrentBlockRect = 0;
emit leftMouseClicked(m_view->mapFromScene(x, y).x(), m_view->mapFromScene(x, y).y(), m_CurrentBlockRect != 0);
}
void QGraphicsInput::rightMouseRelease(qreal x, qreal y)
{
QGraphicsItem *it = this->itemAt(x, y);
if (it) {
if (it->data(1).toString() == "block") {
m_CurrentBlockRect = (QGraphicsRectItem *) it;
}
} else
m_CurrentBlockRect = 0;
emit rightMouseClicked(m_view->mapFromScene(x, y).x(), m_view->mapFromScene(x, y).y(), m_CurrentBlockRect != 0);
}
int QGraphicsInput::nearActiveBorder(qreal x, qreal y)
{
if (m_LastSelected == 0)
return 0;
x = m_LastSelected->mapFromScene(x, y).x();
y = m_LastSelected->mapFromScene(x, y).y();
qreal xcenter = m_LastSelected->rect().center().x();
qreal ycenter = m_LastSelected->rect().center().y();
qreal xcd = abs(m_LastSelected->rect().right() - xcenter) + 8;
qreal ycd = abs(m_LastSelected->rect().bottom() - ycenter) + 8;
if ((abs(x - m_LastSelected->rect().left()) <= 4)) {
if (abs(y - ycenter) < ycd)
return 1;
else
return 0;
}
if ((abs(m_LastSelected->rect().top() - y) <= 4)) {
if (abs(x - xcenter) < xcd)
return 2;
else
return 0;
}
if ((abs(x - m_LastSelected->rect().right()) <= 4)) {
if (abs(y - ycenter) < ycd)
return 3;
else
return 0;
}
if ((abs(m_LastSelected->rect().bottom() - y) <= 4)) {
if (abs(x - xcenter) < xcd)
return 4;
else
return 0;
}
return 0;
}
QRect QGraphicsInput::getActiveBlock()
{
return QRectF2Rect(m_LastSelected->rect());
}
QRect QGraphicsInput::getCurrentBlock()
{
return QRectF2Rect(m_CurrentBlockRect->rect());
}
void QGraphicsInput::deleteCurrentBlock()
{
if (m_CurrentBlockRect != 0)
deleteBlockRect(m_CurrentBlockRect);
}
void QGraphicsInput::deleteBlock(int index)
{
int count = 0;
for (int i = 0; i < items().count(); i++) {
if (items().at(i)->data(1) == "block") {
if (index == count) {
deleteBlockRect((QGraphicsRectItem *)items().at(i));
return;
}
count++;
}
}
}
void QGraphicsInput::clearBlocks() // KEEP
{
for (int i = items().count() - 1; i >= 0; i--) {
if (items().at(i)->data(1) == "block") {
deleteBlockRect((QGraphicsRectItem *)items().at(i));
}
}
}
void QGraphicsInput::setMagnifierCursor(QCursor *cursor)
{
delete magnifierCursor;
magnifierCursor = new QCursor(cursor->pixmap());
}
void QGraphicsInput::addToolBarAction(QAction *action)
{
actionList.append(action);
}
void QGraphicsInput::addToolBarSeparator()
{
QAction * action = new QAction(" | ", 0);
action->setEnabled(false);
actionList.append(action);
}
void QGraphicsInput::setToolBarVisible()
{
if (toolbar.isNull())
return;
if (actionList.at(0)->text() == QString::fromUtf8("<<")) {
for (int i = 1; i < actionList.count(); i++)
actionList.at(i)->setVisible(false);
toolbar->setMaximumWidth(32);
toolbar->setMinimumWidth(32);
actionList.at(0)->setText(QString::fromUtf8(">>"));
} else {
for (int i = 1; i < actionList.count(); i++)
actionList.at(i)->setVisible(true);
toolbar->setMaximumWidth(480);
toolbar->setMinimumWidth(480);
actionList.at(0)->setText(QString::fromUtf8("<<"));
}
}
void QGraphicsInput::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent)
{
if (wheelEvent->modifiers() == Qt::ControlModifier) {
int delta = wheelEvent->delta();
qreal coeff = delta < 0 ? 1 / (1 - delta / (360.)) : 1 + delta / (240.);
if (coeff >= 1)
emit increaseMe();
else
emit decreaseMe();
wheelEvent->accept();
m_view->viewport()->setCursor(*magnifierCursor);
} else
QGraphicsScene::wheelEvent(wheelEvent);
}
void QGraphicsInput::keyReleaseEvent(QKeyEvent *keyEvent)
{
if (keyEvent->key() == Qt::Key_Control)
m_view->viewport()->setCursor(Qt::ArrowCursor);
if (keyEvent->modifiers() & Qt::ControlModifier) {
if ((keyEvent->key() == Qt::Key_Plus) || (keyEvent->key() == Qt::Key_Equal)) {
emit increaseMe();
return;
}
if ((keyEvent->key() == Qt::Key_Minus) || (keyEvent->key() == Qt::Key_Underscore)) {
emit decreaseMe();
return;
}
}
if (keyEvent->key() > Qt::Key_F1) {
emit keyPressed((int)keyEvent->key());
}
}
void QGraphicsInput::clearTransform()
{
if (m_view) {
QTransform tr = m_view->transform();
tr.reset();
m_view->setTransform(tr);
}
}
void QGraphicsInput::keyPressEvent(QKeyEvent *keyEvent)
{
if (keyEvent->key() == Qt::Key_Control) {
m_view->viewport()->setCursor(*magnifierCursor);
//QApplication::
}
}
void QGraphicsInput::drawLine(int x1, int y1, int x2, int y2)
{
QPen pen(QColor("red"));
pen.setWidth(2);
this->addLine(x1, y1, x2, y2, pen);
}
void QGraphicsInput::imageOrigin(QPoint &p)
{
p.setX(m_image->mapToScene(0,0).x());
p.setY(m_image->mapToScene(0,0).y());
}
QPixmap QGraphicsInput::getCurrentImage()
{
return (m_image->pixmap());
}
void QGraphicsInput::addBlockColliding(Block block)
{
QGraphicsRectItem *gi = newBlock(block);
m_CurrentBlockRect = gi;
QGraphicsTextItem * gte = new QGraphicsTextItem(QString::number(block.blockNumber()), gi);
gte->setFont(QFont("Arial", 16));
gte->setDefaultTextColor(QColor("white"));
gte->moveBy(block.x(), block.y());
}
yagf-0.9.2.1/src/popplerdialog.h 0000664 0001750 0001750 00000002367 12247205425 017145 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef POPPLERDIALOG_H
#define POPPLERDIALOG_H
#include
namespace Ui {
class PopplerDialog;
}
class PopplerDialog : public QDialog
{
Q_OBJECT
public:
explicit PopplerDialog(QWidget *parent = 0);
~PopplerDialog();
QString getPDFFile();
QString getStartPage();
QString getStopPage();
private slots:
void on_checkBox_toggled(bool checked);
void on_pushButton_clicked();
private:
Ui::PopplerDialog *ui;
};
#endif // POPPLERDIALOG_H
yagf-0.9.2.1/src/tpage.cpp 0000664 0001750 0001750 00000032176 12250140707 015733 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "tpage.h"
#include "imagebooster.h"
#include "settings.h"
#include "ccbuilder.h"
#include "CCAnalysis.h"
#include "PageAnalysis.h"
#include "analysis.h"
#include
#include
#include
#include
#include
#include
#include
Page::Page(const int pid, QObject *parent) :
QObject(parent), selectedBlock(0,0,0,0)
{
imageLoaded = false;
loadedBefore = false;
ccbuilder = NULL;
rotation = 0;
deskewed = false;
preprocessed = false;
mFileName.clear();
this->pid = pid;
}
Page::~Page()
{
delete ccbuilder;
}
bool Page::loadFile(QString fileName, bool loadIntoView)
{
// TODO: перенести в TPages.
/*if ((fileName != "") && (sideBar->getFileNames().contains(fileName))) {
sideBar->select(fileName);
sideBar->clearBlocks();
for (int i = 0; i < graphicsInput->blocksCount(); i++)
sideBar->addBlock(graphicsInput->getBlockRectByIndex(i).toRect());
}*/
if (fileName == "") {
if(mFileName.isEmpty()) return false;
fileName = mFileName;
}
rotation = 0;
crop1.setX(0);
crop1.setY(0);
crop1.setWidth(0);
crop1.setHeight(0);
scale = 0.5;
QImageReader ir(fileName);
ir.setScaledSize(QSize(ir.size().width()/2, ir.size().height()/2));
img2 = ir.read();
imageLoaded = !img2.isNull();
if (!imageLoaded)
return false;
if (ccbuilder){
delete ccbuilder;
ccbuilder = 0;
}
if (!loadedBefore) {
settings = Settings::instance();
if (settings->getCropLoaded()) {
ccbuilder = new CCBuilder(img2);
ccbuilder->setGeneralBrightness(360);
ccbuilder->setMaximumColorComponent(100);
QRect r = ccbuilder->crop();
crop1 = r;
img2 = img2.copy(crop1);
delete ccbuilder;
ccbuilder = 0;
// ccbuilder = new CCBuilder(img2);
}
//ccbuilder->labelCCs();
//mGeneralBrightness = ccbuilder->getGB();
} else {
if (settings->getCropLoaded())
img2 = img2.copy(crop1);
}
rotateImageInternal(img2, rotation);
scaleImages();
mFileName = fileName;
loadedBefore = true;
return true;
}
QPixmap Page::displayPixmap()
{
return QPixmap::fromImage(currentImage());
}
QImage Page::thumbnail()
{
return img16;
}
bool Page::makeLarger()
{
if (scale >= 0.5) return false;
if (scale < 0.2) {
scale = 0.2;
return true;
}
if (scale < 0.25) {
scale = 0.25;
return true;
}
if (scale < 0.5)
scale = 0.5;
return true;
}
bool Page::makeSmaller()
{
if (scale <= 0.125) {
return false;
}
if (scale > 0.25) {
scale = 0.25;
return true;
}
if (scale > 0.2) {
scale = 0.2;
return true;
}
if (scale > 0.125)
scale = 0.125;
return true;
}
void Page::rotate(qreal angle)
{
rotateImageInternal(img2, angle);
rotation += angle;
scaleImages();
clearBlocks();
}
void Page::unload()
{
if (ccbuilder){
delete ccbuilder;
ccbuilder = 0;
}
img2 = QImage(0,0,QImage::Format_ARGB32);
img4 = QImage(0,0,QImage::Format_ARGB32);
img6 = QImage(0,0,QImage::Format_ARGB32);
img8 = QImage(0,0,QImage::Format_ARGB32);
img16 = QImage(0,0,QImage::Format_ARGB32);
imageLoaded = false;
}
inline bool qrects_equal(QRect &r1, QRect &r2)
{
if (abs(r1.x() - r2.x()) > 2)
return false;
if (abs(r1.y() - r2.y()) > 2)
return false;
if (abs(r1.width() - r2.width()) > 2)
return false;
if (abs(r1.height() - r2.height()) > 2)
return false;
return true;
}
void Page::addBlock(Block block)
{
QRect r = block;
normalizeRect(r);
bool add = true;
foreach (Block b, blocks) {
QRect r1 = b;
if (r == r1) {
add = false;
break;
}
}
if (add) {
block.setRect(r.x(), r.y(), r.width(), r.height());
blocks.append(block);
}
sortBlocksInternal();
renumberBlocks();
}
void Page::deleteBlock(const Block &b)
{
blocks.removeOne(b);
sortBlocksInternal();
renumberBlocks();
}
void Page::deleteBlock(const QRect &r)
{
QRect rx = r;
normalizeRect(rx);
foreach (Block b, blocks) {
QRect r1 = b;
if (qrects_equal(rx, r1)) {
blocks.removeAll(b);
break;
}
}
sortBlocksInternal();
renumberBlocks();
}
Block Page::getBlock(const QRect &r)
{
QRect rn =r;
normalizeRect(rn);
foreach (Block b, blocks) {
QRect r1 = b;
if (qrects_equal(rn,r1)) {
scaleRect(b);
return b;
}
}
return Block(0,0,0,0);
}
Block Page::getBlock(int index)
{
Block b = blocks.at(index);
scaleRect(b);
return b;
}
int Page::blockCount()
{
return blocks.count();
}
void Page::clearBlocks()
{
blocks.clear();
}
void Page::savePageForRecognition(const QString &fileName)
{
QImageReader ir(mFileName);
QImage image = ir.read();
applyTransforms(image, 1);
image.save(fileName, "BMP");
}
bool Page::savePageAsImage(const QString &fileName, const QString &format)
{
QImageReader ir(mFileName);
QImage image = ir.read();
//applyTransforms(image, 1);
return image.save(fileName, format.toAscii().data());
}
void Page::saveRawBlockForRecognition(QRect r, const QString &fileName)
{
normalizeRect(r);
saveBlockForRecognition(r, fileName, "BMP");
}
void Page::saveBlockForRecognition(QRect r, const QString &fileName, const QString &format)
{
int oldw = r.width();
int oldh = r.height();
r.setX(r.x()*2);
r.setY(r.y()*2);
r.setWidth(oldw*2);
r.setHeight(oldh*2);
QImageReader ir(mFileName);
QImage image = ir.read();
applyTransforms(image, 1);
image.copy(r).save(fileName, format.toAscii().data());
}
void Page::saveBlockForRecognition(int index, const QString &fileName)
{
saveBlockForRecognition(blocks.at(index), fileName, "BMP");
}
void Page::selectBlock(const QRect &r)
{
QRect rn =r;
normalizeRect(rn);
foreach (Block b, blocks) {
QRect r1 = b;
if (rn == r1) {
selectedBlock = b;
break;
}
}
}
Block Page::getSelectedBlock()
{
return selectedBlock;
}
void Page::deskew(bool recreateCB)
{
if (deskewed) return;
if (imageLoaded) {
prepareCCBuilder();
CCAnalysis * an = new CCAnalysis(ccbuilder);
if (an->analize()) {
QImage timg = tryRotate(img2, -atan(an->getK())*360/6.283);
CCBuilder * cb2 = new CCBuilder(timg);
cb2->setGeneralBrightness(360);
cb2->setMaximumColorComponent(100);
cb2->labelCCs();
CCAnalysis * an2 = new CCAnalysis(cb2);
an2->analize();
qreal angle = -atan(an2->getK())*360/6.283;
delete an2;
delete cb2;
if (abs(angle*10) >= abs(5))
angle += (-atan(an->getK())*360/6.283);
else
angle = -atan(an->getK())*360/6.283;
rotate(angle);
deskewed = true;
delete ccbuilder;
ccbuilder = 0;
if (recreateCB)
prepareCCBuilder();
}
delete an;
}
}
void Page::rotate90CW()
{
rotate(90);
}
void Page::rotate90CCW()
{
rotate(-90);
}
void Page::rotate180()
{
rotate(180);
}
void Page::blockAllText()
{
prepareCCBuilder();
clearBlocks();
BlockSplitter bs;
bs.setImage(img2, rotation, scale);
QRect r = bs.getRootBlock(currentImage());
addBlock(r);
}
QList Page::splitInternal() {
clearBlocks();
BlockSplitter bs;
//rotation = 0;
bs.setImage(img2, 0, 0.5);// sideBar->getScale());
bs.splitBlocks();
return bs.getBlocks();
}
void Page::prepareCCBuilder()
{
if (!ccbuilder) {
ccbuilder = new CCBuilder(img2);
ccbuilder->setGeneralBrightness(360);
ccbuilder->setMaximumColorComponent(100);
ccbuilder->labelCCs();
}
}
bool Page::splitPage(bool preprocess)
{
QList blocks;
prepareCCBuilder();
if (preprocess) {
QString fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr());
saveTmpPage(fn, !preprocessed, !preprocessed, false);
loadedBefore = false;
loadFile(fn);
blocks = splitInternal();
/*if (blocks.count() == 0) {
deskew();
fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr());
saveTmpPage(fn, true, false);
loadedBefore = false;
loadFile(fn);
blocks = splitInternal();
}*/
if (!preprocessed) {
fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr());
if (blocks.count() == 0) {
saveTmpPage(fn, false, false, true, 2);
} else {
saveTmpPage(fn, false, false, false, 7, 5);
}
loadedBefore = false;
loadFile(fn);
blocks = splitInternal();
}
preprocessed = true;
} else {
deskew();
blocks = splitInternal();
}
qreal sf = 2.0*scale;
foreach (Rect block, blocks) {
QRect r;
block.x1 *=sf;
block.y1 *=sf;
block.x2 *= sf;
block.y2 *=sf;
r.setX(block.x1);
r.setY(block.y1);
r.setWidth(block.x2 - block.x1);
r.setHeight(block.y2 - block.y1);
addBlock(r);
}
return blocks.count() != 0;
}
QString Page::fileName()
{
return mFileName;
}
int Page::pageID()
{
return pid;
}
void Page::sortBlocksInternal()
{
sortBlocks(blocks);
}
bool Page::isDeskewed()
{
return deskewed;
}
bool Page::isPreprocessed()
{
return preprocessed;
}
qreal Page::getRotation()
{
return rotation;
}
void Page::setDeskewed(bool value)
{
deskewed = value;
}
void Page::setPreprocessed(bool value)
{
preprocessed = value;
}
void Page::applyTransforms(QImage &image, qreal scale)
{
scale = scale*2;
QRect crop;
crop.setX(crop1.x()*scale);
crop.setY(crop1.y()*scale);
crop.setWidth(crop1.width()*scale);
crop.setHeight(crop1.height()*scale);
image = image.copy(crop);
rotateImageInternal(image, rotation);
}
void Page::rotateImageInternal(QImage &image, qreal angle)
{
qreal x = image.width() / 2;
qreal y = image.height() / 2;
image = image.transformed(QTransform().translate(-x, -y).rotate(angle).translate(x, y), Qt::SmoothTransformation);
}
void Page::scaleImages()
{
img4 = img2.scaledToWidth(img2.width() / 2);
img6 = img2.scaledToWidth(img2.width() / 2.5);
img8 = img4.scaledToWidth(img4.width() / 2);
img16 = img8.scaledToWidth(img8.width() / 2);
}
void Page::normalizeRect(QRect &rect)
{
qreal oldw = rect.width();
qreal oldh = rect.height();
rect.setX(rect.x()*0.5/scale);
rect.setY(rect.y()*0.5/scale);
rect.setWidth(oldw*0.5/scale);
rect.setHeight(oldh*0.5/scale);
}
void Page::scaleRect(QRect &rect)
{
qreal oldw = rect.width();
qreal oldh = rect.height();
rect.setX(rect.x()/0.5*scale);
rect.setY(rect.y()/0.5*scale);
rect.setWidth(oldw/0.5*scale);
rect.setHeight(oldh/0.5*scale);
}
QImage Page::tryRotate(QImage image, qreal angle)
{
qreal x = image.width() / 2;
qreal y = image.height() / 2;
return image.transformed(QTransform().translate(-x, -y).rotate(angle).translate(x, y), Qt::SmoothTransformation);
}
QImage Page::currentImage()
{
if (scale <= 0.125)
return img8;
if (scale <= 0.2)
return img6;
if (scale <= 0.25)
return img4;
return img2;
}
void Page::saveTmpPage(const QString &fileName, bool cc, bool boost, bool brighten, int p, int q)
{
QImageReader ir(mFileName);
QImage image = ir.read().convertToFormat(QImage::Format_ARGB32);
if (image.isNull())
return;
ImageBooster booster;
if (boost)
booster.boost(&image);
if (brighten)
booster.brighten(&image,p,q);
if (cc) {
deskewed = false;
deskew(false);
}
// booster.flatten(&image);
applyTransforms(image, 1);
image.save(fileName, "BMP");
}
void Page::renumberBlocks()
{
for (int i = 0; i < blocks.count(); i++) {
blocks[i].setBlockNumber(i+1);
}
}
yagf-0.9.2.1/src/spellchecker.h 0000664 0001750 0001750 00000003335 12250140707 016737 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef SPELLCHECKER_H
#define SPELLCHECKER_H
#include
#include
#include
typedef QMap StringMap;
class QTextEdit;
class QRegExp;
class QTextCursor;
class QStringList;
class SpellChecker
{
public:
SpellChecker(QTextEdit *textEdit);
~SpellChecker();
void unSpellCheck();
void setLanguage(const QString &lang);
bool spellCheck(); //Returns false only if the dictionary not found. Otherwise always true.
void checkWord();
void enumerateDicts();
bool hasDict(const QString &shname);
QStringList suggestions();
private:
void _checkWord(QTextCursor *cursor);
QTextEdit *m_textEdit;
QRegExp *m_regExp;
QString m_lang1;
QString m_lang2;
StringMap *m_map;
AspellConfig *spell_config1;
AspellConfig *spell_config2;
AspellSpeller *spell_checker1;
AspellSpeller *spell_checker2;
QStringList *dictList;
QString bad_language;
};
#endif // SPELLCHECKER_H
yagf-0.9.2.1/src/ccbuilder.h 0000664 0001750 0001750 00000005522 12247205425 016234 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef CCBUILDER_H
#define CCBUILDER_H
#include
#include
#include
#include
#include
//#define DEBUG_CC
typedef QList IntList;
/*
This class builds a 2-dimensional array for an image in which the connected pixels are labeled with the same numbers.
The elements of the resulting array may be accesed using the label() method.
*/
class CCBuilder : public QObject
{
Q_OBJECT
public:
/* pixmap is the image to be analysed */
explicit CCBuilder(const QImage &img, QObject *parent = 0);
~CCBuilder();
/* This method sets the threshold for the basckround. If pixel r+g+b value is greater than this value the pixel is considered
as the (white) background. Otherwise it is considered as the foregraound to be analyzed. */
void setGeneralBrightness(int value);
void setMaximumColorComponent(int value);
/* This method resets CCs labels so that they occupy a continuos range of numbers */
void compactLabels();
/* This method returns the label value for original image's x and y. */
quint32 label(int x, int y);
/* This method performs the actual connected component's labeling */
int labelCCs();
/* Returns image width */
int width();
/* Returns image height */
int height();
QRect crop();
int getGB();
signals:
public slots:
private:
void initialScan();
void backwardScan();
void forwardScan();
int labelChecked(int x, int y);
void setLabel(int x, int y, int newValue);
void relabelLineLR(int y);
void relabelLineRL(int y);
bool isForeground(QRgb value);
void scanFirstLineLR();
void scanLineLR(int y);
void labelLeftmostPoint(int y);
void labelRightmostPoint(int y);
int generalBrightness;
int maximumComponentBrightness;
QImage image;
quint32 * labels;
bool * flags;
bool skipNext;
IntList recolor;
quint32 maxlabel;
bool didRecolor;
int w, h;
QRect cropRect;
#ifdef DEBUG_CC
int dcounter;
int gcounter;
#endif
friend class Cropper;
};
#endif // CCBUILDER_H
yagf-0.9.2.1/src/scanner.h 0000664 0001750 0001750 00000003605 12250140707 015724 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef SCANNER_H
#define SCANNER_H
#include
#include
#include
class ScannerBase : public QObject
{
Q_OBJECT
public:
explicit ScannerBase(QObject *parent = 0);
~ScannerBase();
void addParameter(const QString &s);
void addEnvironmentVar(const QString &s);
void setOutputFile(const QString &s);
QString programName();
virtual void exec() = 0;
signals:
void processFinished();
public slots:
private slots:
void finished( int, QProcess::ExitStatus );
protected:
void waitFor();
void execInternal(const QString &s);
void setProgramName(const QString &s);
void setPreloadLibrary(const QString &s);
private:
QProcess scanProcess;
QStringList parameters;
QStringList environment;
QString outputFile;
QString pName;
QString preloadLibrary;
};
class ScannerFactory {
public:
ScannerFactory();
QStringList frontEnds();
ScannerBase * createScannerFE(const QString &name);
private:
QString findPreloadLibrary();
void findFEs();
private:
QString preloadPath;
QStringList fes;
};
#endif // SCANNERBASE_H
yagf-0.9.2.1/src/advancedconfigdialog.ui 0000664 0001750 0001750 00000004165 12247205425 020603 0 ustar parallels parallels
AdvancedConfigDialog00400115Advanced SettingsCrop Image When LoadedtrueQt::Vertical2040Qt::HorizontalQDialogButtonBox::Cancel|QDialogButtonBox::OkbuttonBoxaccepted()AdvancedConfigDialogaccept()248254157274buttonBoxrejected()AdvancedConfigDialogreject()316260286274
yagf-0.9.2.1/src/sidebar.cpp 0000664 0001750 0001750 00000010762 12247205425 016246 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "sidebar.h"
#include "qsnippet.h"
#include
#include
#include
#include
#include
#include
#include
SideBar::SideBar(QWidget *parent) :
QListWidget(parent)
{
//setDragDropOverwriteMode(true);
current = 0;
setMaximumWidth(120);
setMinimumWidth(120);
connect(this, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(itemActive(QListWidgetItem*,QListWidgetItem*)));
setToolTip(trUtf8("Drop files here"));
setAcceptDrops(true);
setDropIndicatorShown(true);
lock = false;
}
void SideBar::itemActive(QListWidgetItem *item, QListWidgetItem *item2)
{
if (lock) return;
lock = true;
if (item) {
emit pageSelected(((QSnippet *)item)->pageID());
current = ((QSnippet *)item);
} else current = 0;
lock = false;
}
/*void SideBar::dragEnterEvent(QDragEnterEvent *event)
{
if (!event->mimeData()->hasUrls()) {
setCursor(Qt::ForbiddenCursor);
event->ignore();
// >mimeData()->setData("application/x-qabstractitemmodeldatalist", QByteArray());
}
else {
setCursor(Qt::DragCopyCursor);
event->accept();
}
QListWidget::dragEnterEvent(event);
}*/
QStringList SideBar::mimeTypes() const
{
QStringList qstrList;
qstrList.append("text/uri-list");
return qstrList;
}
Qt::DropActions SideBar::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
bool SideBar::dropMimeData(int index, const QMimeData *data, Qt::DropAction action)
{
// if (action == Qt::MoveAction)
// return false;
QList urlList;
urlList = data->urls(); // retrieve list of urls
QStringList files;
foreach(QUrl url, urlList) // iterate over list
{
files.append(url.toLocalFile());
++index; // increment index to preserve drop order
}
emit filesDropped(files);
return true;
}
void SideBar::startDrag(Qt::DropActions supportedActions)
{
supportedActions |= Qt::MoveAction;
QDrag * drag = new QDrag(this);
QMimeData *mimeData = new QMimeData();
QList urlList;
QStringList sl;
foreach(QListWidgetItem * lwi, selectedItems()) {
QString s = QString::number(((QSnippet *)lwi)->pageID());
sl << s;
}
mimeData->setUrls(urlList);
drag->setMimeData(mimeData);
if (drag->exec(supportedActions,Qt::CopyAction) == Qt::CopyAction) {
foreach(QListWidgetItem * lwi, selectedItems()) {
emit fileRemoved(((QSnippet *) lwi)->pageID());
model()->removeRow(row(lwi));
}
}
current = 0;
}
QSnippet * SideBar::getItemByName(const QString &name)
{
for (int i = 0; i < count(); i++) {
if (((QSnippet *)item(i))->getName() == name)
return ((QSnippet *)item(i));
}
return NULL;
}
void SideBar::select(const QString &name)
{
current = getItemByName(name);
if (current)
current->setSelected(true);
}
void SideBar::selectFirstFile()
{
if (count() == 0) {
current = NULL;
return;
}
current = (QSnippet *) item(0);
}
/*void SideBar::dragLeaveEvent(QDragLeaveEvent *event)
{
setCursor(Qt::ArrowCursor);
event->accept();
//QListWidget::dragLeaveEvent(event);
}
void SideBar::dropEvent(QDropEvent *event)
{
if (event->mimeData()->hasUrls()) {
QList ul = event->mimeData()->urls();
QList::Iterator i;
for (i = ul.begin(); i != ul.end(); i++) {
QUrl url = *i;
this->addFile(url.toLocalFile());
}
}
setCursor(Qt::ArrowCursor);
event->accept();
//QListWidget::dropEvent(event);
}*/
yagf-0.9.2.1/src/BlockAnalysis.cpp 0000664 0001750 0001750 00000030341 12247205425 017366 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "BlockAnalysis.h"
#include
#include
#include
#include
#include
//#define DEBUG
BlockAnalysis::BlockAnalysis(QPixmap *pixmap)
{
m_image = new QImage((pixmap->toImage().convertToFormat(QImage::Format_RGB32)));
badImage = m_image->isNull();
this->m_coords = new QRect(m_image->rect());
m_blockMap = NULL;
}
BlockAnalysis::~BlockAnalysis()
{
deleteBlock();
delete m_image;
}
void BlockAnalysis::newBlock()
{
/*deleteBlock();
m_blockMap = new char * [m_coords->height() - m_coords->top()];
for (int i = 0; i < m_coords->height() - m_coords->top(); i++)
m_blockMap[i] = new char[m_coords->width() - m_coords->left()];
for (int i = m_coords->top(); i < m_coords->height(); i++) {
QRgb * line = (QRgb *) m_image->scanLine(i);
for (int j = m_coords->left(); j < m_coords->width(); j++) {
if ((qRed(line[j]) + qGreen(line[j]) + qBlue(line[j])) < treshold)
m_blockMap[i-m_coords->top()][j-m_coords->left()] = 0;
else
m_blockMap[i-m_coords->top()][j-m_coords->left()] = 128;
}
}*/
}
void BlockAnalysis::deleteBlock()
{
if (m_blockMap != NULL) {
for (int i = 0; i < m_coords->height() - m_coords->top(); i++)
delete m_blockMap[i];
delete m_blockMap;
m_blockMap = NULL;
}
}
void BlockAnalysis::countLinesInImg(int factor, int d)
{
int ftmp = factor;
if (m_image->isNull())
return;
for (int i = m_coords->top(); i < m_coords->height(); i++) {
int l = i;
linesInfo[i] = 0;
ftmp = factor;
for (int j = m_coords->left(); j < m_coords->width(); j++) {
int k = qRed(lines[l][j]) + qGreen(lines[l][j]) + qBlue(lines[l][j]);
if (k >= mtreshold - 1) {
linesInfo[i]++;
#ifdef DEBUG
if (d != 0)
m_image->setPixel(j, l, (1 << 32) + 1);
#endif
} else
break;
ftmp--;
if (ftmp == 0) {
ftmp = factor;
l -= d;
if ((l < m_coords->top()) || (l == m_coords->height()))
break;
}
}
}
longestLine[2] = longestLine[1];
longestLine[1] = longestLine[0];
longestLine[0] = linesInfo[0];
for (int i = m_coords->top(); i < m_coords->height() ; i++)
if (linesInfo[i] > longestLine[0])
longestLine[0] = linesInfo[i];
longestCount[2] = longestCount[1];
longestCount[1] = longestCount[0];
longestCount[0] = 0;
for (int i = m_coords->top(); i < m_coords->height(); i++) {
if (longestLine[0] - linesInfo[i] < 5)
longestCount[0]++;
}
#ifdef DEBUG
QImage im = m_image->copy(*m_coords);
im.save("/home/andrei/ttt.jpg", "JPEG");
#endif
}
void BlockAnalysis::countLinesInImg(QImage *_image)
{
mtreshold = 0;
linesInfo = new quint16[_image->rect().height() + _image->rect().top()];
for (int i = 0; i < _image->rect().height() + _image->rect().top(); i++)
linesInfo[i] = 0;
lines = new QRgb * [_image->rect().height() + _image->rect().top()];
for (int i = _image->rect().top() + _image->rect().height() / 8; i < _image->rect().height() - _image->rect().height() / 8; i++) {
QRgb *line = (QRgb *)(m_image->scanLine(i));
lines[i] = line;
for (int j = _image->rect().left() + _image->rect().width() / 8; j < _image->rect().width() - _image->rect().width() / 8; j++) {
mtreshold = mtreshold + qRed(line[j]) + qGreen(line[j]) + qBlue(line[j]);
}
}
int div = (_image->rect().height() - _image->rect().top()) * (_image->rect().width() - _image->rect().left());
mtreshold = mtreshold / div;
if (_image->isNull())
return;
for (int i = _image->rect().top() + _image->rect().height() / 8; i < _image->rect().height() - _image->rect().height() / 8; i++) {
for (int j = _image->rect().left() + _image->rect().width() / 8; j < _image->rect().width() - _image->rect().width() / 8; j++) {
int k = qRed(lines[i][j]) + qGreen(lines[i][j]) + qBlue(lines[i][j]);
if (k >= mtreshold - 1) {
linesInfo[i]++;
#ifdef DEBUG
if (d != 0)
m_image->setPixel(j, l, (1 << 32) + 1);
#endif
} else
break;
}
}
longestLine[2] = longestLine[1];
longestLine[1] = longestLine[0];
longestLine[0] = linesInfo[0];
for (int i = _image->rect().top(); i < _image->rect().height() ; i++)
if (linesInfo[i] > longestLine[0])
longestLine[0] = linesInfo[i];
longestCount[2] = longestCount[1];
longestCount[1] = longestCount[0];
longestCount[0] = 0;
for (int i = _image->rect().top(); i < _image->rect().height(); i++) {
if (longestLine[0] - linesInfo[i] < 5)
longestCount[0]++;
}
#ifdef DEBUG
QImage im = m_image->copy(*m_coords);
im.save("/home/andrei/ttt.jpg", "JPEG");
#endif
delete lines;
delete linesInfo;
}
int BlockAnalysis::getSkew2()
{
int ll[7], lc[7];
for (int i = 0; i < 7; i++) {
QMatrix m;
m.rotate((i - 3) * 2);
QImage img = m_image->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32);
img = img.copy(img.rect());
countLinesInImg(&img);
ll[i] = longestLine[0];
lc[i] = longestCount[0];
}
int imax = 0;
for (int i = 0; i < 7; i++) {
if ((ll[i] > ll[imax]) && (lc[i] > lc[imax])) {
imax = i;
}
}
int result = (imax - 3) * 2;
return result;
}
int BlockAnalysis::getSkew1()
{
createLinesInfo();
preScan1();
int ll, lc;
int ll1, lc1, div1, dir1;
int ll2, lc2, div2, dir2;
if (m_coords->width() > 1024)
m_coords->setWidth(1024);
if (m_coords->height() > m_coords->width() / 2)
m_coords->setHeight(m_coords->width() / 2);
countLinesInImg(m_coords->width(), 0);
ll = longestLine[0];
lc = longestCount[0];
int div = 2;
int direction = 1;
countLinesInImg(m_coords->width() / div, direction);
int safe = 0;
while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) {
div++;
countLinesInImg(m_coords->width() / div, direction);
safe++;
}
ll1 = longestLine[0];
lc1 = longestCount[0];
div1 = div;
dir1 = direction;
longestLine[0] = ll;
longestCount[0] = lc;
div = 2;
direction = - direction;
countLinesInImg(m_coords->width() / div, direction);
safe = 0;
while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) {
div++;
countLinesInImg(m_coords->width() / div, direction);
safe++;
}
ll2 = longestLine[0];
lc2 = longestCount[0];
div2 = div;
dir2 = direction;
int rdir;
int rdiv;
if ((ll1 > ll2) && (lc1 > lc2)) {
rdir = dir1;
rdiv = div1;
} else {
rdir = dir2;
rdiv = div2;
}
float result = atan(((float)(rdiv - 1)) / ((float)m_coords->width()) * rdir) / M_2_PI * 360;
QMatrix m;
m.rotate(result);
QImage *tmp = m_image;
m_image = new QImage(tmp->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32));
delete tmp;
tmp = m_image;
m_image = new QImage(tmp->scaled(QSize(tmp->width(), tmp->height()) * 1.1).convertToFormat(QImage::Format_RGB32));
delete tmp;
*m_coords = m_image->rect();
delete linesInfo;
delete lines;
createLinesInfo();
preScan1();
countLinesInImg(m_coords->width(), 0);
if ((ll > longestLine[0]) && (lc > longestCount[0])) {
result = 0;
}
// if (((float)longestLine[0])/((float)m_coords->width()) < 0.8)
// result = 0;
delete linesInfo;
delete lines;
return result;
}
int BlockAnalysis::getSkew()
{
createLinesInfo();
preScan1();
int ll, lc;
if (m_coords->width() > 1536)
m_coords->setWidth(1536);
if (m_coords->height() > m_coords->width() / 2)
m_coords->setHeight(m_coords->width() / 2);
countLinesInImg(m_coords->width(), 0);
ll = longestLine[0];
lc = longestCount[0];
countLinesInImg(m_coords->width() / 4, -1);
countLinesInImg(m_coords->width() / 4, 1);
int maxRes = 0;
if ((longestLine[1] >= longestLine[maxRes]) && (longestCount[1] > longestCount[maxRes]))
maxRes = 1;
if ((longestLine[2] >= longestLine[maxRes]) && (longestCount[2] > longestCount[maxRes]))
maxRes = 2;
int direction = 0;
if (maxRes == 0) direction = 1;
else if (maxRes == 1) direction = -1;
else
return 0;
int div = 4;
countLinesInImg(m_coords->width() / div, direction);
int safe = 0;
while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) {
div++;
countLinesInImg(m_coords->width() / div, direction);
direction = - direction;
safe++;
}
float result = atan(((float)(div - 1)) / ((float)m_coords->width()) * (direction)) / M_2_PI * 360;
QMatrix m;
m.rotate(result);
QImage *tmp = m_image;
m_image = new QImage(tmp->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32));
*m_coords = m_image->rect();
delete linesInfo;
delete lines;
delete tmp;
createLinesInfo();
preScan1();
countLinesInImg(m_coords->width(), 0);
if ((ll > longestLine[0]) && (lc > longestCount[0]))
result = 0;
if (((float)longestLine[0]) / ((float)m_coords->width()) < 0.8)
result = 0;
delete linesInfo;
delete lines;
return result;
}
void BlockAnalysis::preScan1()
{
mtreshold = 0;
for (int i = m_coords->top(); i < m_coords->height(); i++) {
QRgb *line = (QRgb *)(m_image->scanLine(i));
lines[i] = line;
for (int j = m_coords->left(); j < m_coords->width(); j++) {
mtreshold = mtreshold + qRed(line[j]) + qGreen(line[j]) + qBlue(line[j]);
}
}
int div = (m_coords->height() - m_coords->top()) * (m_coords->width() - m_coords->left());
mtreshold = mtreshold / div;
for (int i = m_coords->top(); i < m_coords->height(); i++) {
//qint16 pixel1 = qRed(lines[i][m_coords->left()]) + qGreen(lines[i][m_coords->left()]) + qBlue(lines[i][m_coords->left()]);
//qint16 pixel2 = qRed(lines[i][m_coords->left() + 1]) + qGreen(lines[i][m_coords->left() + 1]) + qBlue(lines[i][m_coords->left() + 1]);
for (int j = m_coords->left() + 2; j < m_coords->width(); j++) {
qint16 pixel3 = qRed(lines[i][j]) + qGreen(lines[i][j]) + qBlue(lines[i][j]);
if (pixel3 >= mtreshold) {
lines[i][j-1] = lines[i][j];
lines[i][j-2] = lines[i][j];
}
//pixel1 = pixel2;
//pixel2 = pixel3;
}
lines[i][m_coords->width()-1] = lines[i][m_coords->width()-2];
}
for (int i = m_coords->height() - 1; i >= 0; i--) {
if (longestLine[0] - linesInfo[i] > 2) {
m_coords->setHeight(i + 1);
break;
}
}
for (int i = m_coords->top(); i < m_coords->height(); i++) {
if (longestLine[0] - linesInfo[i] > 2) {
m_coords->setTop(i);
break;
}
}
}
void BlockAnalysis::createLinesInfo()
{
linesInfo = new quint16[m_coords->height() + m_coords->top()];
for (int i = 0; i < m_coords->height() + m_coords->top(); i++)
linesInfo[i] = 0;
lines = new QRgb * [m_coords->height() + m_coords->top()];
}
yagf-0.9.2.1/src/forcelocaledialog.ui 0000600 0001750 0001750 00000005433 12250076477 020122 0 ustar parallels parallels
ForceLocaleDialog00400203DialogGroupBoxRadioButtonRadioButtonRadioButtonTextLabelQt::Vertical2040Qt::HorizontalQDialogButtonBox::Cancel|QDialogButtonBox::OkbuttonBoxaccepted()ForceLocaleDialogaccept()248254157274buttonBoxrejected()ForceLocaleDialogreject()316260286274
yagf-0.9.2.1/src/droplabel.cpp 0000664 0001750 0001750 00000003540 12247205425 016575 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "droplabel.h"
#include
#include
#include
#include
#include
#include
#include
#include
DropLabel::DropLabel(QWidget *parent, Qt::WindowFlags f) : QLabel(parent, f)
{
setAcceptDrops(true);
}
void DropLabel::dragEnterEvent(QDragEnterEvent *event)
{
//event->setDropAction(Qt::IgnoreAction);
const QMimeData * md = event->mimeData();
QStringList sl = md->formats();
if (!md->formats().contains("text/uri-list")) {
setCursor(Qt::ForbiddenCursor);
}
else {
event->setDropAction(Qt::MoveAction);
event->accept();
//QCursor cur(lw->selectedItems().at(0)->icon().pixmap(96, 128));
//setCursor(cur);
}
}
void DropLabel::dragLeaveEvent(QDragLeaveEvent *event)
{
setCursor(Qt::ArrowCursor);
event->accept();
}
void DropLabel::dropEvent(QDropEvent *event)
{
if (event->dropAction() == Qt::MoveAction)
event->ignore();
else
event->accept();
}
void DropLabel::setListWidget(QListWidget *w)
{
lw = 0;
}
yagf-0.9.2.1/src/translations/ 0000775 0001750 0001750 00000000000 12250673454 016651 5 ustar parallels parallels yagf-0.9.2.1/src/translations/ts_update.sh 0000775 0001750 0001750 00000000371 12247205425 021174 0 ustar parallels parallels #!/bin/sh
lupdate -noobsolete ../mainform.cpp ../mainform.ui ../popplerdialog.ui ../configdialog.ui ../advancedconfigdialog.ui ../main.cpp ../spellchecker.cpp ../sidebar.cpp ../settings.cpp -ts yagf_ru.ts yagf_lt.ts yagf_de.ts yagf_pl.ts yagf_uk.ts
yagf-0.9.2.1/src/translations/yagf_lt.ts 0000664 0001750 0001750 00000054371 12247205425 020653 0 ustar parallels parallels
AdvancedConfigDialogAdvanced SettingsSudėtingesni nustatymaiCrop Image When LoadedApkarpyti įkeltą paveikslėlįConfigDialogOCR SettingsOCR nustatymaiOCR EngineOCR varikliscuneiformcuneiformtesseracttesseractTesseract SetupTesseract nustatymaiLocation of the tessdata directory:Tesseract direktorijos vieta:MainFormRecognition languageAtpažinimo kalbaOpen ImageAtverti failąImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)Grafiniai failai (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)There is an unsaved text in the editor window. Do you want to save it?Rengyklės lange yra neišsaugotas tekstas. Išsaugoti?WarningPerspėjimasErrorKlaidaNo image loadedGrafinio failo įkelti nepavykoStarting cuneiform failedNepavyko paleisti „Cuneiform“ programosThe system said: Sistemos atsakymas:program not foundprogramos rasti nepavykoAbout YAGFApie YAGFhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlRecognizing pages...Atpažįstami puslapiai...AbortNutrauktiSave ImageĮrašyti paveikslėlįImporting pages from the PDF document...Importuojami puslapiai iš PDF dokumento...CancelAtšauktiNo compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).Nerasta tinkama PDF konvertavimo priemonė. Prašome įdiegti „pdftoppm“ įrankį arba „GrostScript“ programų paketą (iš jo bus reikalinga programa „gs“).PDF file name may not be emptyPDF failo vardas negali būti tuščiasSelect an existing directory for output or create some new onePasirinkite egzistuojantį aplanką sukuriamiems failams arba sukurkite naująSelecting DirectoryPasirenkamas aplankasThe selected directory is not emptyPasirinktas aplankas netuščiasStarting tesseract failedNepavyko paleisti tesseractcuneiform not found, switching to tesseractNepavyko rasti cuneiform, perjungiama į tesseractNo recognition engine found.
Please install either cuneiform or tesseractNepavyko rasti jokio atpažinimo variklio.
Prašome įdiegti cuneiform arba tesseract.tesseract not found, switching to cuneiformTesseract nerastas, perjungiama į cuneiformNo PDF converter installedNeįdiegtas PDF konvertuoklis<p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details.GPL v3. Jei norite sužinoti plačiau, aplankykite <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> svetainę.Using CuneiformUsing TesseractScanning is impossibleNo scanning front-end is found. Please install XSane in order to perform scanning.Failed to Load ImageFailed to detect text areas on this page.
The page possibly lacks contrast. Try to select blocks manually.The selected directoy is not empty. Please select or create another one.Failed to save the project.Failed to load project.MainWindowS&can...S&kenuoti...Scanning images using XSane...Puslapis skenuojamas naudojant „XSane“...&Save text...&Įrašyti tekstą&Open Image...&Atverti grafinį failą...Open ImageAtverti grafinį failą&Recognize&Atpažinti tesktąRecognizing text...Atpažįstamas tekstas...Choose &Language&Parinkti kalbąQuitIšeitiPrevious pageAnkstesnis puslapisMove to previous imageEiti prie ankstesnio puslapioNext pageKitas puslapisMove to next imageEiti prie tolimesnio puslapioOnline HelpPagalba interneteAbout...Apie programą...Recognize &All PagesAtpažinti &visus puslapiusRecognize All PagesAtpažinti visus puslapiusCtrl+AVald+AClear all blocksIšvalyti visus pažymėjimusDelete the current blockIštrinti šį pažymėjimąRecognize blockAtpažinti pažymėjimąRecognize this blockAtpažinti šį pažymėjimąClear numbersIšvalyti skaičiusCrear block numberingIšvalyti pažymėjimų numeravimąCheck spellingTikrinti rašybąSave current image...Įrašyti šį paveikslėlį...Save currently opened image in its real sizeIšsaugoti šiuo metu atvertą paveikslėlį realiu dydžiuSave blockIšsaugoti pažymėjimąSave the current block to the image fileĮrašyti dabartinį pažymėjimą į paveikslėlio failąSelect HTML formatPasirinkti HTML formatąSelect HTML format as recognition outputPasirinkti HTML formatą kaip atpažinimo išvestįLarger viewPadidintiSmaller viewSumažintiRotate 90 CCWPasukti 90 laipsnių prieš laikr. rodyklęRotate 180Pasukti 180 laipsniųRotate 90 CWPasukti 90 laipsnių pagal laikr. rodyklę&File&Failas&Help&PagalbaCopy To ClipboardKopijuoti į atmintinęCopy recognized text to clipboardKopijuoti tekstą į atmintinęMainWindowPagrindinisLangastoolBarįrankiųJuostaCtrl+NVald+NCtrl+SVald+SCtrl+OVald+OCtrl+RVald+RCtrl+QVald+Q&Settings&Nustatymai<<<<Hide/Show ToolbarSlėpti/Rodyti įrankių juostąImport from PDF...Importuoti iš PDF...Import pages from PDF documentsImportuoti puslapius iš PDF dokumentoOCR SettingsOCR nustatymaiSet up the OCR parametersNustatykite OCR parametrusPaste ImageĮterpti paveikslėlįPaste image from clipboardĮterpti paveikslėlį iš iškarpinėsSelect Text AreaPažymėkite teksto sritįDeskew BlockIštiesinti pažymėjimąDeskew the current blockIštiesinti dabartinį pažymėjimąDeskewIštiesintiCorrect the page skew Pataisyti puslapio kreivumą Advanced SettingsSudėtingesni nustatymaiThe settings you should probably never changeNustatymai, kurių ko gero geriau niekada nekeistiselect multiple blocksSplits text into several blocksToggle Large/Small IconstoolBar_2Select Recognition LanguagePrepare PageSave Project...Load Project...Prepare the page for recognitionPopplerDialogImport from PDFImportuoti iš PDFFile NameFailo pavadinimasSelect...Pažymėti...PagesPuslapiaiFromNuoToIkiEntire DocumentVisą dokumentąQObjectJPEG Files (*.jpg)JPEG failai (*.jpg)PNG Files (*.png)PNG failai (*.png)Failed to save the imageNepavyko įrašyti paveikslėlioRequired spelling dictionary (%1) is not found.
Spell-checking is disabled.
Try to install an appropriate aspell dictionary.Reikiamo rašybos tikrinimo žodyno (%1) rasti nepavyko
Rašybos tikrinimas išjungtas.
Prašome įdiegti reikiamą aspell žodyną.WarningPerspėjimasSelect Project DirectoryBulgarianCzechDanishDutchEnglishFrenchGermanHungarianItalianLatvianLithuanianPolishPortugueseRomanianRussianRussian-EnglishSpanishSerbianSlovenianSwedishUkrainianFinnishGerman GothicGreekHebrewNorwegianSlovakSwedish GothicTurkishSideBarDrop files hereMeskite failus čia
yagf-0.9.2.1/src/translations/yagf_pl.ts 0000664 0001750 0001750 00000052451 12247205425 020644 0 ustar parallels parallels
AdvancedConfigDialogAdvanced SettingsCrop Image When LoadedConfigDialogOCR SettingsOCR EnginecuneiformtesseractTesseract SetupLocation of the tessdata directory:MainFormRecognition languageJęzyk rozpoznawaniaOpen ImageOtwórz plik graficznyImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)Pliki graficzne (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)There is an unsaved text in the editor window. Do you want to save it?W oknie edytora jest niezapisany tekst. Zapisać?WarningOstrzeżenieErrorBłądNo image loadedBrak załadowanego obrazkaStarting cuneiform failedNie udało się uruchomić cuneiformThe system said: Odpowiedź systemu:program not foundnie znaleziono programuAbout YAGFО programiehttp://symmetrica.net/cuneiform-linux/yagf-en.htmlhttp://symmetrica.net/cuneiform-linux/yagf-pl.htmlSave ImageRecognizing pages...Rozpoznaję strony...AbortPrzerwijImporting pages from the PDF document...CancelNo compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).PDF file name may not be emptySelect an existing directory for output or create some new oneSelecting DirectoryThe selected directory is not emptyStarting tesseract failedcuneiform not found, switching to tesseractNo recognition engine found.
Please install either cuneiform or tesseracttesseract not found, switching to cuneiformNo PDF converter installed<p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details.Using CuneiformUsing TesseractScanning is impossibleNo scanning front-end is found. Please install XSane in order to perform scanning.Failed to Load ImageFailed to detect text areas on this page.
The page possibly lacks contrast. Try to select blocks manually.The selected directoy is not empty. Please select or create another one.Failed to save the project.Failed to load project.MainWindowS&can...S&kanuj...Scanning images using XSane...Skanuję strony używając XSane...&Save text...&Zapisz tekst...&Open Image...&Otwórz plik graficzny...Open ImageOtwórz plik graficzny&Recognize&РаспознатьRecognizing text...Rozpoznaj tekst...Choose &Language&Wybierz językQuitZakończPrevious pagePoprzednia stronaMove to previous imagePrzejdź do poprzedniej grafikiNext pageNastępna stronaMove to next imagePrzejdź do następnej grafikiOnline HelpPomoc onlineAbout...O programie...Clear all blocksOczyść wszystkie blokiDelete the current blockUsuń bieżący blokRecognize blockRozpoznaj blokRecognize this blockRozpoznaj ten blokClear numbersCrear block numberingCheck spellingSprawdzanie pisowniSave current image...Save currently opened image in its real sizeSave blockSave the current block to the image fileSelect HTML formatSelect HTML format as recognition outputLarger viewPowiększ widokSmaller viewZmniejsz widokRotate 90 CCWObróć o 90 stopni w lewoRotate 180Obróć o 180 stopniRotate 90 CWObróć o 90 stopni w lewo&File&Plik&Help&PomocCopy To ClipboardKopiuj do schowkaCopy recognized text to clipboardSkopiuj rozpoznany tekst do schowkaMainWindowtoolBarCtrl+NCtrl+SCtrl+OCtrl+RCtrl+QRecognize &All PagesRozpoznaj &wszystkie strony Recognize All PagesRozpoznaj wszystkie stronyCtrl+A&Settings<<Hide/Show ToolbarImport from PDF...Import pages from PDF documentsOCR SettingsSet up the OCR parametersPaste ImagePaste image from clipboardSelect Text AreaDeskew BlockDeskew the current blockDeskewCorrect the page skew Advanced SettingsThe settings you should probably never changeselect multiple blocksSplits text into several blocksToggle Large/Small IconstoolBar_2Select Recognition LanguagePrepare PageSave Project...Load Project...Prepare the page for recognitionPopplerDialogImport from PDFFile NameSelect...PagesFromToEntire DocumentQObjectJPEG Files (*.jpg)PNG Files (*.png)Failed to save the imageRequired spelling dictionary (%1) is not found.
Spell-checking is disabled.
Try to install an appropriate aspell dictionary.WarningOstrzeżenieSelect Project DirectoryBulgarianCzechDanishDutchEnglishFrenchGermanHungarianItalianLatvianLithuanianPolishPortugueseRomanianRussianRussian-EnglishSpanishSerbianSlovenianSwedishUkrainianFinnishGerman GothicGreekHebrewNorwegianSlovakSwedish GothicTurkishSideBarDrop files here
yagf-0.9.2.1/src/translations/yagf_de.ts 0000664 0001750 0001750 00000055122 12247205425 020617 0 ustar parallels parallels
AdvancedConfigDialogAdvanced SettingsErweiterte EinstellungenCrop Image When LoadedBild nach dem Laden beschneidenConfigDialogOCR SettingsOCR EinstellungenOCR EnginecuneiformtesseractTesseract SetupTesseract EinstellungenLocation of the tessdata directory:Ort des tessdata Verzeichnisses:MainFormRecognition languageErkennungs-SpracheOpen ImageBild öffnenImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)Bilddateien (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)There is an unsaved text in the editor window. Do you want to save it?Nicht gespeicherter Text im Bearbeitungsfenster. Jetzt speichern?WarningWarnungErrorFehlerStarting cuneiform failedDer Start von "Cuneiform" schlug fehlThe system said: Das System sagt:program not foundProgramm nicht gefundenNo image loadedKein Bild geöffnetAbout YAGFÜber YAGFhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlRecognizing pages...Erkenne Seiten...AbortAbbruchSave ImageBild speichernImporting pages from the PDF document...Seiten aus dem PDF Dokument importieren...CancelAbbrechenNo compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).Es konnte keine kompatible PDF Konvertierungssoftware gefunden werden. Bitte installieren Sie entweder pdftoppm aus dem Paket poppler oder das GhostScript Paket (aus diese wird der "gs" Befehl gebraucht).PDF file name may not be emptyPDF Dateiname darf nicht leer seinSelect an existing directory for output or create some new oneWählen Sie ein bestehendes Verzeichnis für die Ausgabe oder erstellen sie ein neuesSelecting DirectoryVerzeichnis auswählenThe selected directory is not emptyDas ausgewählte Verzeichnis ist nicht leerStarting tesseract failedtesseract startete nichtcuneiform not found, switching to tesseractcuneiform nicht gefunden, wechsle zu tesseractNo recognition engine found.
Please install either cuneiform or tesseractKeine Erkennungs Engine gefunden.
Bitte cuneiform und/oder tesseract installierentesseract not found, switching to cuneiformtesseract nicht gefunden, wechsel zu cuneiformNo PDF converter installedKein PDF Konvertierer installiert<p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details.<p align="center"><b>YAGF - Yet Another Graphical Front-end (Noch ein weiteres grafisches Frontend) fürr cuneiform und tesseract OCR (Optical Character Recognition = Optische Zeichen Erkennung) engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> Dies ist freie Softwater die unter der GPL v3 verbreitet wird. Besuchen Sie <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> für weitere Informationen. {2009-2012?}Using CuneiformUsing TesseractScanning is impossibleNo scanning front-end is found. Please install XSane in order to perform scanning.Failed to Load ImageFailed to detect text areas on this page.
The page possibly lacks contrast. Try to select blocks manually.The selected directoy is not empty. Please select or create another one.Failed to save the project.Failed to load project.MainWindowMainWindowHauptfensterLarger viewAnsicht vergrößernSmaller viewAnsicht verkleinernRotate 90 CCWUm 90° gegen den UZS drehenRotate 180Um 180° drehenRotate 90 CWUm 90° im UZS drehen&File&Datei&Help&HilfetoolBarWerkzeugleisteS&can...Bild ei&nlesen...Scanning images using XSane...Bilder mit «XSane» einlesen...Ctrl+NCtrl+N&Save text...Text &speichern...Ctrl+SCtrl+S&Open Image...Bild &öffnen...Open ImageBild öffnenCtrl+OCtrl+O&RecognizeTexte&rkennung: aktuelle SeiteRecognizing text...Texterkennung...Ctrl+RCtrl+RChoose &Language&Wählen Sie eine SpracheQuitB&eendenCtrl+QCtrl+QPrevious pageVorherige SeiteMove to previous imageZum vorherigen Bild wechselnNext pageNächste SeiteMove to next imageZum nächsten Bild wechselnOnline HelpOnline-&HilfeAbout...Ü&ber...Copy To ClipboardIn die Zwischenablage kopierenCopy recognized text to clipboardText in die Zwischenablage kopierenRecognize &All PagesTexterkennung: &alle SeitenRecognize All PagesTexterkennung: alle SeitenCtrl+ACtrl+AClear all blocksAlle Markierungen entfernenDelete the current blockAktuelle Markierung entfernenRecognize blockTexterkennung: aktuelle MarkierungRecognize this blockDiese Markierung erkennenClear numbersNummern löschenCrear block numberingMarkierungsnummerierung löschenCheck spellingRechtschreibprüfungSave current image...Aktuelles Bild speichern...Save currently opened image in its real sizeAktuelles Bild mit wirklicher Auflösung speichernSave blockBlock speichernSave the current block to the image fileAktuellen Block in die Bilddatei speichernSelect HTML formatHTML Format auswählenSelect HTML format as recognition outputHTML Format als Ausgabe der Erkennung wählen&SettingsEin&stellungen<<Hide/Show ToolbarWerkzeugleiste anzeigen/verbergenImport from PDF...Aus PDF importieren ...Import pages from PDF documentsSeiten aus PDF Dokumenten importierenOCR SettingsOCR EinstellungenSet up the OCR parametersOCR Parameter einstellenPaste ImageBild einfügenPaste image from clipboardBild der Zwischenablage einfügenSelect Text AreaTextbereich auwählenDeskew BlockBlock entzerrenDeskew the current blockAktuellen Block entzerrenDeskewEntzerrenCorrect the page skew Seitenverzerrung korrigierenAdvanced SettingsErweiterte EinstellungenThe settings you should probably never changeEinstellungen die sie wahrscheinlich nie ändern solltenselect multiple blocksMehrere Blöcke auswählenSplits text into several blocksTeilt Text in mehrere BlöckeToggle Large/Small IconsGroße/kleine IconstoolBar_2Select Recognition LanguagePrepare PageSave Project...Load Project...Prepare the page for recognitionPopplerDialogImport from PDFAus PDF importierenFile NameDateinameSelect...Auswählen...PagesSeitenFromVonTobisEntire DocumentGanzes DokumentQObjectJPEG Files (*.jpg)JPEG Dateien (*.jpg)PNG Files (*.png)PNG Dateien (*.png)Failed to save the imageSpeichern des Bilds schlug fehlRequired spelling dictionary (%1) is not found.
Spell-checking is disabled.
Try to install an appropriate aspell dictionary.Erforderliches (%1) Wörterbuch nicht gefunden.
Rechtschreibprüfung ist deaktiviert.
Bitte entsprechendes aspell Wörterbuch installieren.WarningWarnungSelect Project DirectoryBulgarianCzechDanishDutchEnglishFrenchGermanHungarianItalianLatvianLithuanianPolishPortugueseRomanianRussianRussian-EnglishSpanishSerbianSlovenianSwedishUkrainianFinnishGerman GothicGreekHebrewNorwegianSlovakSwedish GothicTurkishSideBarDrop files hereDateien hier ablegen
yagf-0.9.2.1/src/translations/yagf_uk.ts 0000664 0001750 0001750 00000061401 12247205425 020643 0 ustar parallels parallels
AdvancedConfigDialogAdvanced SettingsРозширені налаштуванняCrop Image When LoadedОбрізати зображення після завантаженняConfigDialogOCR SettingsНалаштування розпізнаванняOCR EngineРушій розпізнаванняcuneiformCuneiformtesseractTesseractTesseract SetupНалаштування TesseractLocation of the tessdata directory:Розташування теки tessdataMainFormRecognition languageМова розпізнаванняOpen ImageВідкрити зображенняImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)Файли зображення (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)There is an unsaved text in the editor window. Do you want to save it?У вікні редактора незбережений текст. Зберегти?WarningПопередженняErrorПомилкаNo image loadedНема завантажених зображеньStarting cuneiform failedНе вдалось запустити cuneiformThe system said: Система пише: program not foundпрограму не знайденоAbout YAGFПро програмуhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlSave ImageЗберегти зображенняRecognizing pages...Розпізнавання сторінки…AbortСкасуватиImporting pages from the PDF document...Імпорт сторінок з PDF-документаCancelСкасуватиNo compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).Не знайдено перетворювач PDF-документів. Пропонуємо встановити або програму pdftoppm, або покет GhostScript (достатньо виконуваного файла gs).PDF file name may not be emptyНазва PDF-файла не може бути порожньоюSelect an existing directory for output or create some new oneВиберіть існуючу теку для виводу результату або створіть новуSelecting DirectoryВибрати текуThe selected directory is not emptyВибрана тека непорожняStarting tesseract failedНевдалий запуск tesseractcuneiform not found, switching to tesseractНе знайдено cuneiform, перемикаємось у tesseractNo recognition engine found.
Please install either cuneiform or tesseractНе знайдено жодного рушія з розпізнавання.
Просимо встановити або cuneiform, або tesseracttesseract not found, switching to cuneiformtesseract не знайдено, перкмикаємось у cuneiformNo PDF converter installedНе встановлено PDF-конвертера<p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details.<p align="center"><b>YAGF - Ще один графічний фронт-енд (Yet Another Graphical Front-end) для рушіїв з розпізнавання cuneiform та tesseract</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> Це вільне програмне забезпечення, яке поширюється піл ліцензією GPL v3. Відвідайте <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> , щоб отримати більше інформації.Using CuneiformUsing TesseractScanning is impossibleNo scanning front-end is found. Please install XSane in order to perform scanning.Failed to Load ImageFailed to detect text areas on this page.
The page possibly lacks contrast. Try to select blocks manually.The selected directoy is not empty. Please select or create another one.Failed to save the project.Failed to load project.MainWindowS&can...Зі&сканувати…Scanning images using XSane...Сканування зображень, використовуючи XSane…&Save text...&Зберегти текст…&Open Image...&Відкрити зображення…Open ImageВідкрити зображення&Recognize&РозпізнатиRecognizing text...Розпізнавання тексту…Choose &LanguageВибрати &мовуQuitВийтиPrevious pageПопередня сторінкаMove to previous imageПерейти до попереднього зображенняNext pageНаступна сторінкаMove to next imageПерейти до наступного зображенняOnline HelpДовідка в інтернетіAbout...Про програму…Clear all blocksОчистити всі блокиDelete the current blockВилучити теперішній блокRecognize blockРозпізнати блокRecognize this blockРозпізнати цей блокClear numbersОчистити номериCrear block numberingОчистити блок нумераціїCheck spellingПеревірити орфографіюSave current image...Зберегти теперішнє зображення…Save currently opened image in its real sizeЗберегти теперішнє відкрите зображення в справжньому розміріSave blockЗберегти блокSave the current block to the image fileЗберегти цей блок як зображенняSelect HTML formatВиділити формат HTMLSelect HTML format as recognition outputВиділити формат HTML як результат розпізнаванняLarger viewЗбільшитиSmaller viewЗменшитиRotate 90 CCWПеревернути на 90 градусів проти часової стрілкиRotate 180Перевернути на 180 градусівRotate 90 CWПеревернути на 90 градусів за часовою стрілкою&File&Файл&Help&ДовідкаCopy To ClipboardСкопіювати до кишеніCopy recognized text to clipboardСкопіювати розпізнаний текст у кишенюMainWindowГоловне вікноtoolBarПанель інструментівCtrl+NCtrl+NCtrl+SCtrl+SCtrl+OCtrl+OCtrl+RCtrl+RCtrl+QCtrl+QRecognize &All PagesРозпізнати &всі сторінкиRecognize All PagesРозпізнати всі сторінкиCtrl+ACtrl+A&Settings&Налаштування<<<<Hide/Show ToolbarСховати/відобразити панель інструментівImport from PDF...Імпортувати з PDFImport pages from PDF documentsІмпортувати сторінки з PDF-документівOCR SettingsНалаштування розпізнаванняSet up the OCR parametersКонфігурування параметрів розпізнаванняPaste ImageВставити зображенняPaste image from clipboardВставити зображення з буферу обмінуSelect Text AreaВибрати текстовий блокDeskew BlockВирівняти блокDeskew the current blockВирівняти поточний блокDeskewВирівнятиAdvanced SettingsРоширені налаштуванняThe settings you should probably never changeНалаштування, які ви скоріш за все ніколи не змінюватиметеselect multiple blocksвибрати кілька блоківSplits text into several blocksРозділити текст на декілька окремих блоківToggle Large/Small IconsПеремикнути великі/маленькі піктограмиtoolBar_2Correct the page skew Select Recognition LanguagePrepare PageSave Project...Load Project...Prepare the page for recognitionPopplerDialogImport from PDFІмпортувати з PDFFile NameНазва файлаSelect...Виберіть...PagesСторінкиFromВідToАдресатEntire DocumentДокумент повністюQObjectJPEG Files (*.jpg)Файли JPEG (*.jpg)PNG Files (*.png)Файли PNG (*.png)Failed to save the imageНе вдалось зберегти зображенняRequired spelling dictionary (%1) is not found.
Spell-checking is disabled.
Try to install an appropriate aspell dictionary.Потрібні словники орфографії (%1) не знайдено.
Перевірку орфографії вимкнено.
Спробуйте встановити відповідний словник aspell.WarningПопередженняSelect Project DirectoryBulgarianCzechDanishDutchEnglishFrenchGermanHungarianItalianLatvianLithuanianPolishPortugueseRomanianRussianRussian-EnglishSpanishSerbianSlovenianSwedishUkrainianFinnishGerman GothicGreekHebrewNorwegianSlovakSwedish GothicTurkishSideBarDrop files hereПересуньте файли сюди
yagf-0.9.2.1/src/translations/yagf_ru.ts 0000664 0001750 0001750 00000063221 12247205425 020654 0 ustar parallels parallels
AdvancedConfigDialogAdvanced SettingsДополнительные настройкиCrop Image When LoadedОбрезать изображение при загрузкеConfigDialogOCR SettingsНастройки программ распознаванияOCR EngineПрограмма распознаванияcuneiformcuneiformtesseracttesseractTesseract SetupНастройка tesseractLocation of the tessdata directory:Расположение директории tessdata:MainFormRecognition languageЯзык распознаванияOpen ImageОткрыть файлImage Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)Графические файлы (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)There is an unsaved text in the editor window. Do you want to save it?В окне редактора несохраненный текст. Сохранить?WarningПредупреждениеErrorОшибкаNo image loadedИзображение не загруженоStarting cuneiform failedНе удалось запустить cuneiformThe system said: Ответ системы:program not foundпрограмма не найденаAbout YAGFО программеhttp://symmetrica.net/cuneiform-linux/yagf-en.htmlhttp://symmetrica.net/cuneiform-linux/yagf-ru.htmlSave ImageСохранить изображениеRecognizing pages...Распознаем страницы...AbortПрерватьImporting pages from the PDF document...Импорт страниц из документа PDF...CancelОтменитьNo compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).Не найдены подходящие конверторы PDF. Установите, пожалуйста, утилиту pdftoppm или пакет GhostScript (из которого требуется программа gs).PDF file name may not be emptyНеобходимо указать имя файла PDFSelect an existing directory for output or create some new oneВыберите существующую директорию для вывода или создайте новуюSelecting DirectoryВыбор директорииThe selected directory is not emptyВыбранная директория - не пустаяStarting tesseract failedНе удалось запустить tesseractcuneiform not found, switching to tesseractПрограмма cuneiform не найдена, переключаемся на tesseractNo recognition engine found.
Please install either cuneiform or tesseractПрограмма распознавания не найдена.
Установите, пожалуйста, cuneiform или tesseracttesseract not found, switching to cuneiformПрограмма tesseract не найдена, переключаемся на cuneiformNo PDF converter installedКонвертер PDF не установлен<p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details.<p align="center"><b>YAGF - Графическая оболочка для программ распознавания текста cuneiform и tesseract</b></p><p align="center">Версия %1</p> <p align="center">Ⓒ 2009-2012 Андрей Боровский</p> YAGF - открытое программное обеспечение, которое распространяется на условиях лицензии GPL v3. Вы найдете подробности на странице <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-ru.html</a>.Using CuneiformИспользуется CuneiformUsing TesseractИспользуется TesseractScanning is impossibleСканирование невозможноNo scanning front-end is found. Please install XSane in order to perform scanning.Программа сканирования не найдена. Необходимо установить XSane.Failed to Load ImageНевозможно загруить выбранное изобажениеFailed to detect text areas on this page.
The page possibly lacks contrast. Try to select blocks manually.Не удалось найти ткстовые области на странице. Возможно, изображение отсканировано со слишком низким контрастом. Попробуйт выделить блоки вручную.The selected directoy is not empty. Please select or create another one.Выбранный каталог содержит файлы. Выберите пустой каталог или создайте новый.Failed to save the project.Ошибка при сохранении проекта.Failed to load project.Невозможно открыть проект.MainWindowS&can...С&канировать...Scanning images using XSane...Сканируем страницу с помощью XSane...&Save text...&Сохранить текст...&Open Image...&Открыть графический файл...Open ImageОткрыть графический файл&Recognize&РаспознатьRecognizing text...Распознать текст...Choose &Language&Выбрать языкQuitВыйтиPrevious pageПредыдущее изображениеMove to previous imageПерейти к предыдущему изображениюNext pageСледующее изображениеMove to next imageПерейти к следующему изображениюOnline HelpСправка онлайнAbout...О програме...Clear all blocksОчистить все блокиDelete the current blockУдалить этот блокRecognize blockРаспознать блокRecognize this blockРаспознать этот блокClear numbersCrear block numberingCheck spellingПроверить орфографиюSave current image...Сохранить изображение...Save currently opened image in its real sizeСохраняет полученное изображение в реальном размереSave blockСохранить блокSave the current block to the image fileСохранить этот блок в графическом файлеSelect HTML formatВыбрать формат HTMLSelect HTML format as recognition outputВыбрать HTML в качестве формата вывода распознанного текстаLarger viewУвеличитьSmaller viewУменьшитьRotate 90 CCWПовернуть на 90 градусов против часовой стрелкиRotate 180Повернуть на 180 градусовRotate 90 CWПовернуть на 90 градусов по часовой стрелке&File&Файл&Help&СправкаCopy To ClipboardКопировать текст в буфер обменаCopy recognized text to clipboardКопировать текст в буфер обменаMainWindowtoolBarCtrl+NCtrl+SCtrl+OCtrl+RCtrl+QRecognize &All PagesРаспознать &всё Recognize All PagesРаспознать все страницыCtrl+A&Settings&Настройки<<Hide/Show ToolbarПоказать/убрать панельImport from PDF...Импорт из документа PDF...Import pages from PDF documentsИмпорт страниц из документа PDFOCR SettingsНастройки программ распознаванияSet up the OCR parametersУстановить параметры программ распознаванияPaste ImageВставить изображениеPaste image from clipboardВставить страницу из буфера обменаSelect Text AreaАвтоматически выделить текстовую областьDeskew BlockВыровнять блокDeskew the current blockВыровнять выделенный блокDeskewВыровнятьCorrect the page skew Исправить наклон страницыAdvanced SettingsДополнительные настройкиThe settings you should probably never changeНастройки, которые вам, скорее всего, менять не нужноselect multiple blocksРазделить текст на блокиSplits text into several blocksРазбить текст на блокиToggle Large/Small IconsБольшие/маленькие иконкиtoolBar_2Select Recognition LanguageВыбор языка распознаванияPrepare PageSave Project...Сохранить проект...Load Project...Загрузить проект...Prepare the page for recognitionПодготовить страницу для распознаванияPopplerDialogImport from PDFИмпорт из документа PDFFile NameИмя файла PDFSelect...Выбрать...PagesСтраницыFromСToпоEntire DocumentВесь документQObjectJPEG Files (*.jpg)Файлы JPEG (*.jpg)PNG Files (*.png)Файлы PNG (*.png)Failed to save the imageНе удалось сохранить файлRequired spelling dictionary (%1) is not found.
Spell-checking is disabled.
Try to install an appropriate aspell dictionary.Требуемый орфографический словарь (%1) не найден.
Проверка орфографии будет отключена.
Попробуйте установить соответствующий словарь aspell.WarningПредупреждениеSelect Project DirectoryВыбор директории проектаBulgarianБолгарскийCzechЧешскийDanishДатскийDutchГолландскийEnglishАнглийскийFrenchФранцузскийGermanНемецкийHungarianВенгерскийItalianИтальянскийLatvianЛатышскийLithuanianЛитовскийPolishПольскийPortugueseПортугальскийRomanianРумынскийRussianРусскийRussian-EnglishРусский-английскийSpanishИспанскийSerbianСербскийSlovenianСловенскийSwedishШведскийUkrainianУкраинскийFinnishФинскийGerman GothicНемецкий готическийGreekГреческийHebrewИвритNorwegianНоревежскийSlovakСловацкийSwedish GothicШведский готическийTurkishТурецкийSideBarDrop files hereПеретащите файлы сюда
yagf-0.9.2.1/src/qxtunixsignalcatcher.cpp 0000664 0001750 0001750 00000005051 12247205425 021100 0 ustar parallels parallels /*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include "qxtunixsignalcatcher.h"
#include "qxtunixscinternal.h"
#include
#include
#include
QXtUnixSignalCatcher * QXtUnixSignalCatcher::sc = NULL;
QMutex * QXtUnixSignalCatcher::mutex = NULL;
QXtUnixSignalCatcher::QXtUnixSignalCatcher(QObject *parent) :
QObject(parent)
{
mutex = new QMutex();
sci = new QXtUnixSignalCatcherInternal(0);
connect(sci, SIGNAL(unixSignalInternal(int)), this, SLOT(doEmit(int)), Qt::QueuedConnection);
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, SIGHUP);
sigaddset(&newset, SIGTERM);
sigaddset(&newset, SIGINT);
sigaddset(&newset, SIGUSR1);
sigaddset(&newset, SIGUSR2);
sigprocmask(SIG_UNBLOCK, &newset, 0);
}
QXtUnixSignalCatcher::QXtUnixSignalCatcher() : QObject(0)
{
}
QXtUnixSignalCatcher::QXtUnixSignalCatcher(QXtUnixSignalCatcher &) : QObject(0)
{
}
QXtUnixSignalCatcher::~QXtUnixSignalCatcher()
{
}
void QXtUnixSignalCatcher::signalHandler(int sig_num)
{
mutex->lock();
sc->emitSignal(sig_num);
mutex->unlock();
}
void QXtUnixSignalCatcher::emitSignal(int sig_num)
{
sci->emitSignal(sig_num);
}
bool QXtUnixSignalCatcher::connectUnixSignalInternal(int sig_num)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sa.sa_handler = signalHandler;
return (sigaction(sig_num, &sa, 0) == 0);
}
bool QXtUnixSignalCatcher::connectUnixSignal(int sig_num)
{
catcher();
return sc->connectUnixSignalInternal(sig_num);
}
void QXtUnixSignalCatcher::disconnectUnixSugnals()
{
sigset_t newset;
sigemptyset(&newset);
sigaddset(&newset, SIGHUP);
sigaddset(&newset, SIGTERM);
sigaddset(&newset, SIGINT);
sigaddset(&newset, SIGUSR1);
sigaddset(&newset, SIGUSR2);
sigprocmask(SIG_BLOCK, &newset, 0);
delete sci;
sci = NULL;
delete mutex;
mutex = NULL;
}
void QXtUnixSignalCatcher::doEmit(int sig_num)
{
emit unixSignal(sig_num);
}
QXtUnixSignalCatcher *QXtUnixSignalCatcher::catcher()
{
if (!sc)
sc = new QXtUnixSignalCatcher(0);
return sc;
}
yagf-0.9.2.1/src/qxtunixsignalcatcher.h 0000664 0001750 0001750 00000002537 12247205425 020553 0 ustar parallels parallels /*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef QXTUNIXSIGNALCTACHER_H
#define QXTUNIXSIGNALCTACHER_H
#include
class QMutex;
class QXtUnixSignalCatcherInternal;
class QXtUnixSignalCatcher : public QObject
{
Q_OBJECT
public:
static QXtUnixSignalCatcher * catcher();
static bool connectUnixSignal(int sig_num);
void disconnectUnixSugnals();
signals:
void unixSignal(int sig_num);
private slots:
void doEmit(int sig_num);
private:
QXtUnixSignalCatcher(QObject *parent = 0);
QXtUnixSignalCatcher();
QXtUnixSignalCatcher(QXtUnixSignalCatcher&);
~QXtUnixSignalCatcher();
static void signalHandler(int sig_num);
void emitSignal(int sig_num);
bool connectUnixSignalInternal(int sig_num);
private:
static QXtUnixSignalCatcher * sc;
static QMutex * mutex;
QXtUnixSignalCatcherInternal * sci;
};
#endif // QXTUNIXSIGNALCTACHER_H
yagf-0.9.2.1/src/mainform.h 0000775 0001750 0001750 00000010564 12250140750 016106 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "settings.h"
#include
#include
#include "ui_mainform.h"
#include
#include
//#include "ui_popplerdialog.h"
class QComboBox;
class QCheckBox;
class QLabel;
class QCloseEvent;
class QPixmap;
class QProcess;
class QByteArray;
class QFile;
class SpellChecker;
class QCursor;
class QGraphicsInput;
class QMenu;
class PDFExtractor;
class ccbuilder;
class QLabel;
const QString version = "0.9.2.1";
class PageCollection;
class ScannerBase;
class MainForm : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
MainForm(QWidget *parent = 0);
~MainForm();
signals:
void windowShown();
private slots:
//void on_actionRecognize_activated();
void on_actionSelect_HTML_format_activated();
void on_actionDeskew_activated();
//void on_alignButton_clicked();
void on_actionCheck_spelling_activated();
void on_actionSave_block_activated();
void on_actionSave_current_image_activated();
void on_actionCheck_spelling_triggered();
void on_actionRecognize_block_activated();
void on_ActionDeleteBlock_activated();
void on_ActionClearAllBlocks_activated();
void loadImage();
void rotateCWButtonClicked();
void rotateCCWButtonClicked();
void rotate180ButtonClicked();
void enlargeButtonClicked();
void decreaseButtonClicked();
void singleColumnButtonClicked();
void newLanguageSelected(int index);
void scanImage();
void loadNextPage();
void loadPreviousPage();
void recognize();
void recognizeAll();
void showAboutDlg();
void showHelp();
void unalignButtonClicked();
void hideToolBar();
void importPDF();
void showConfigDlg();
void addPDFPage(QString pageName);
void finishedPDF();
void pasteimage();
void deskewByBlock();
void selectTextArea();
void selectBlocks();
void setSmallIcons();
void selectHTMLformat();
void loadFiles(QStringList files);
void LangTextChanged(const QString &text);
private:
virtual void closeEvent(QCloseEvent *event);
void initSettings();
void loadFile(const QString &fn, bool loadIntoView = true);
//void loadFileWithPixmap(const QString &fn, const QPixmap &pixmap);
void delTmpFiles();
void delTmpDir();
void preparePageForRecognition();
void prepareBlockForRecognition(const QRect &r);
void prepareBlockForRecognition(int index);
void recognizeInternal();
bool useCuneiform(const QString &inputFile, const QString &outputFile);
bool useTesseract(const QString &inputFile);
QString getFileNameToSaveImage(QString &format);
void loadFromCommandLine();
void clearTmpFiles();
void fillLangBox();
private:
QComboBox *selectLangsBox;
QGraphicsInput *graphicsInput;
QString fileName;
QCursor *resizeCursor;
QCursor *resizeBlockCursor;
bool useXSane;
ScannerBase * scanner;
QByteArray *ba;
//SpellChecker *spellChecker;
QMenu *m_menu;
PDFExtractor * pdfx;
QProgressDialog pdfPD;
int ifCounter;
Settings * settings;
PageCollection * pages;
QLabel * engineLabel;
private slots:
bool findEngine();
void readyRead(int sig);
void setResizingCusor();
void setUnresizingCusor();
void loadPage();
void rightMouseClicked(int x, int y, bool inTheBlock);
void onShowWindow();
void showAdvancedSettings();
void addSnippet(int index);
void preprocessPage();
void saveProject();
void loadProject();
void setUILanguage();
};
yagf-0.9.2.1/src/tpage.h 0000664 0001750 0001750 00000006424 12250140707 015375 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef TPAGE_H
#define TPAGE_H
#include "tblock.h"
#include "analysis.h"
#include
#include
#include
#include
class CCBuilder;
class Settings;
class Page : public QObject
{
Q_OBJECT
public:
explicit Page(const int pid, QObject *parent = 0);
~Page();
bool loadFile(QString fileName, bool loadIntoView = true);
QPixmap displayPixmap();
QImage thumbnail();
bool makeLarger();
bool makeSmaller();
void rotate(qreal angle);
void unload();
void addBlock(Block block);
void deleteBlock(const Block &b);
void deleteBlock(const QRect &r);
Block getBlock(const QRect &r);
Block getBlock(int index);
int blockCount();
void clearBlocks();
void savePageForRecognition(const QString &fileName);
bool savePageAsImage(const QString &fileName, const QString &format);
void saveRawBlockForRecognition(QRect r, const QString &fileName);
void saveBlockForRecognition(QRect r, const QString &fileName, const QString &format);
void saveBlockForRecognition(int index, const QString &fileName);
void selectBlock(const QRect &r);
Block getSelectedBlock();
void deskew(bool recreateCB = true);
void rotate90CW();
void rotate90CCW();
void rotate180();
void blockAllText();
bool splitPage(bool preprocess);
QString fileName();
int pageID();
void sortBlocksInternal();
bool isDeskewed();
bool isPreprocessed();
qreal getRotation();
void setDeskewed(bool value);
void setPreprocessed(bool value);
signals:
void refreshView();
public slots:
private:
void renumberBlocks();
void applyTransforms(QImage &image, qreal scale);
void rotateImageInternal(QImage &image, qreal angle);
void scaleImages();
void normalizeRect(QRect &rect);
void scaleRect(QRect &rect);
QImage tryRotate(QImage image, qreal angle);
QImage currentImage();
void saveTmpPage(const QString &fileName, bool cc,bool boost, bool brighten, int p = 1, int q =1);
QList splitInternal();
void prepareCCBuilder();
private:
qreal scale;
qreal rotation;
int mGeneralBrightness;
QRect crop1;
QRect crop2;
bool deskewed;
QImage img;
QImage img2;
QImage img4;
QImage img6;
QImage img8;
QImage img16;
TBlocks blocks;
bool imageLoaded;
bool loadedBefore;
bool preprocessed;
QString mFileName;
CCBuilder * ccbuilder;
Settings * settings;
int blockPointer;
int pid;
Block selectedBlock;
};
#endif // TPAGE_H
yagf-0.9.2.1/src/tblock.h 0000664 0001750 0001750 00000002371 12250140707 015550 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef TBLOCK_H
#define TBLOCK_H
#include
#include
#include
class Block : public QRect
{
public:
explicit Block( int x, int y, int width, int height );
Block(const QRect &r);
int blockNumber();
void setBlockNumber(const int value);
void setLanguage(const QString &lang);
QString getLanguage();
private:
int number;
QString language;
};
typedef QList TBlocks;
void sortBlocks(TBlocks &blocks);
#endif // TBLOCK_H
yagf-0.9.2.1/src/configdialog.cpp 0000664 0001750 0001750 00000002745 12247205425 017264 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "configdialog.h"
#include "ui_configdialog.h"
#include
#include
ConfigDialog::ConfigDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ConfigDialog)
{
ui->setupUi(this);
}
ConfigDialog::~ConfigDialog()
{
delete ui;
}
void ConfigDialog::setSelectedEngine(int value)
{
if (!value)
ui->radioButton->setChecked(true);
else
ui->radioButton_2->setChecked(true);
}
int ConfigDialog::selectedEngine()
{
if (ui->radioButton->isChecked())
return 0;
return 1;
}
void ConfigDialog::setTessDataPath(const QString &value)
{
ui->lineEdit->setText(value);
}
QString ConfigDialog::tessdataPath()
{
return ui->lineEdit->text();
}
yagf-0.9.2.1/src/tpagecollection.h 0000664 0001750 0001750 00000005645 12250140707 017455 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef TPAGECOLLECTION_H
#define TPAGECOLLECTION_H
#include "tpage.h"
#include
#include
#include
class QSnippet;
class PageCollection : public QObject
{
Q_OBJECT
public:
static PageCollection * instance();
static void clearCollection();
bool appendPage(const QString &fileName);
int count();
bool makePageCurrent(int index);
bool makePageCurrentByID(int id);
void setBeforeFirst(); // the page pointer is set before the first page
bool makeNextPageCurrent();
QSnippet * snippet();
QPixmap pixmap();
void savePageForRecognition(const QString &fileName);
void saveRawBlockForRecognition(QRect r, const QString &fileName);
void saveBlockForRecognition(QRect r, const QString &fileName, const QString &format = "BMP");
void saveBlockForRecognition(int index, const QString &fileName);
int blockCount();
Block getBlock(const QRect &r);
Block getBlock(int index);
void selectBlock(const QRect &r);
Block getSelectedBlock();
bool pageValid();
QString fileName();
bool savePageAsImage(const QString &fileName, const QString &format);
bool isDeskewed();
bool isPreprocessed();
qreal getRotation();
void setRotation(const qreal value);
void setDeskewed(const bool value);
void setPreprocessed(const bool value);
void reloadPage();
public slots:
void makeLarger();
void makeSmaller();
void rotate90CW();
void rotate90CCW();
void rotate180();
void deskew();
void blockAllText();
bool splitPage(bool preprocess);
void addBlock(const QRect & rect);
void deleteBlock(const QRect & rect);
void clearBlocks();
void clear();
signals:
void loadPage(); // The page is already current
void addSnippet(int index);
void cleared();
private slots:
void pageSelected(int id);
void pageRemoved(int id);
private:
PageCollection(QObject *parent = 0);
PageCollection(const PageCollection &);
~PageCollection();
Page * cp();
int id2Index(int id);
private:
QVector pages;
int index;
int pid;
static PageCollection * m_instance;
};
#endif // TPAGECOLLECTION_H
yagf-0.9.2.1/src/pdf2ppt.cpp 0000664 0001750 0001750 00000003034 12247205425 016206 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "pdf2ppt.h"
#include
#include
PDF2PPT::PDF2PPT() : PDFExtractor()
{
}
void PDF2PPT::exec()
{
QString command = "pdftoppm";
QStringList args;
args << "-jpeg";
if ((!getStopPage().isEmpty()) || (getStopPage().toInt() > 0)) {
if (getStartPage().toInt() == 0)
this->setStartPage("1");
args << "-f" << getStartPage() << "-l" << getStopPage();
}
args << "-rx" << "600" << "-ry" << "600" << this->getSourcePDF();
if (!getOutputDir().endsWith("/"))
setOutputDir(getOutputDir().append('/'));
setOutputPrefix(getOutputDir().append("page"));
args << getOutputPrefix();
setOutputExtension("jpg");
execInternal(command, args);
}
yagf-0.9.2.1/src/analysis.cpp 0000664 0001750 0001750 00000032457 12247205425 016465 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-end
Copyright (C) 2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "analysis.h"
#include "utils.h"
#include
bool operator==(Rect r1, Rect r2)
{
if (r1.x1 != r2.x1)
return false;
if (r1.y1 != r2.y1)
return false;
if (r1.x2 != r2.x2)
return false;
if (r1.y2 != r2.y2)
return false;
return true;
}
bool operator==(GlyphInfo g1, GlyphInfo g2)
{
if (g1.x != g2.x)
return false;
if (g1.y != g2.y)
return false;
if (g1.h != g2.h)
return false;
return true;
}
CCAnalysis::CCAnalysis(CCBuilder * builder)
{
this->builder = builder;
glyphCount = 0;
mediumGlyphHeight = 0;
mediumGlyphWidth = 0;
mediumLetterSpace = 0;
mediumWordSpace = 0;
stringsCount = 0;
}
CCAnalysis::~CCAnalysis()
{
}
bool CCAnalysis::analize(bool extractBars)
{
if (extractComponents(extractBars)) {
classifyGlyphs();
normalizeLines();
return true;
}
return false;
}
Bars CCAnalysis::addBars()
{
extractComponents(true);
addBarsHorizontal();
addBarsVertical();
addBarsHorisontalAfterVertical();
return bars;
}
bool CCAnalysis::extractComponents(bool extractBars)
{
components.clear();
for (int y = 0; y < builder->height(); y++) {
for (int x = 0; x < builder->width(); x++) {
quint32 label = builder->label(x,y);
if (label) {
Rect r;
r.dotCount = 0;
r.x1 = builder->width();
r.x2 = 0;
r.y1 = builder->height();
r.y2 = 0;
if (!components.contains(label))
components.insert(label, r);
r = components.value(label);
r.dotCount++;
if (x < r.x1)
r.x1 = x;
if (x > r.x2)
r.x2=x;
if (y r.y2)
r.y2 = y;
components.remove(label);
components.insert(label,r);
}
}
}
quint32 wacc, hacc, count;
wacc = 0;
hacc= 0;
count = 0;
foreach(Rect r, components.values()) {
wacc += (r.x2 - r.x1);
hacc +=(r.y2 - r.y1);
count++;
}
quint32 wmed;
quint32 hmed;
if (count != 0) {
wmed = wacc/count;
hmed = hacc/count;
} else return false;
if (extractBars) {
foreach(quint32 k, components.keys()) {
Rect r = components.value(k);
int deltaX = abs(r.x2 - r.x1); // TODO: remove abs() if not needed
int deltaY = abs(r.y2 - r.y1); // TODO: remove abs() if not needed
if ((deltaX > 10)&&(deltaY > 10)) continue;
if (deltaX != 0) {
if (deltaY/deltaX >= BarRatio) {
components.remove(k);
bars.append(r);
continue;
}
} else {
if (deltaY >= BarRatio) {
components.remove(k);
bars.append(r);
continue;
}
}
if (deltaY != 0) {
if (deltaX/deltaY >= BarRatio) {
components.remove(k);
bars.append(r);
continue;
}
} else {
if (deltaX >= BarRatio) {
components.remove(k);
bars.append(r);
continue;
}
}
}
}
foreach(quint32 k, components.keys()) {
Rect r = components.value(k);
if ((r.x2 - r.x1) > 6*wmed)
components.remove(k);
else {
int s = (r.y2 - r.y1)*(r.x2 - r.x1);
if (( s < 30) || ((r.y2 - r.y1) > 4*hmed))
components.remove(k);
else {
if (s == 0) components.remove(k);
else
if (((double)r.dotCount/(double)s) < 0.1)
components.remove(k);
}
}
}
wacc = 0;
hacc= 0;
count = 0;
foreach(Rect r, components.values()) {
wacc += (r.x2 - r.x1);
hacc +=(r.y2 - r.y1);
count++;
}
if (count == 0) return false;
wmed = wacc/count;
hmed = hacc/count;
mediumGlyphWidth = wmed;
mediumGlyphHeight = hmed;
glyphCount = count;
return true;
}
int CCAnalysis::getGlyphBoxCount()
{
return components.count();
}
Rect CCAnalysis::getGlyphBox(int index)
{
return components.values().at(index);
}
void CCAnalysis::classifyGlyphs()
{
foreach (Rect r, components) {
glyphField.insert(r.x1, r);
}
}
TextLine CCAnalysis::extractLine()
{
Rect first;
//QPoint firstpt;
TextLine line;
for (int x =0; x < builder->width(); x++) {
if (glyphField.values(x).count()) {
first = glyphField.values(x).at(0);
glyphField.remove(x, first);
line.append(ginfo((first.x1+first.x2)/2, (first.y1+first.y2)/2, abs(first.y1-first.y2)));
break;
}
}
if (line.count()) {
Rect temp = first;
while (findAdjacent(temp) >= 0) {
line.append(ginfo((temp.x1+temp.x2)/2, (temp.y1+temp.y2)/2, abs(temp.y1-temp.y2)));
}
}
return line;
}
int CCAnalysis::findAdjacent(Rect &r)
{
int startx = (r.x1+r.x2)/2;
int xspan = (r.x2 - r.x1)*4;
int ymid = (r.y1+r.y2)/2;
int endx = startx + xspan;
for (int x=startx; x = r1.y1) && (ymid <= r1.y2)) {
r = r1;
glyphField.remove(x, r1);
return x;
}
}
}
return -1;
}
void CCAnalysis::normalizeLines()
{
k = 0;
int count = 0;
TextLine l = extractLine();
while (l.count()) {
lines.append(l);
if (l.count() > 4) {
if (abs (l.last().h - l.first().h) < 3) {
qreal d = l.last().x - l.first().x;
if (d != 0) {
k = k + ((qreal)(l.last().y - l.first().y))/d;
count++;
}
} else {
int lastX = l.at(l.count()-1).x;
int lastY = l.at(l.count()-1).y;
int lastH = l.at(l.count()-1).h;
int firstX = l.at(1).x;
int firstY = l.at(1).y;
int firstH = l.at(1).h;
if (abs (lastH - firstH) < 3) {
qreal d = lastX - firstX;
if (d != 0) {
k = k + ((qreal)(lastY - firstY))/d;
count++;
}
}
}
}
//graphicsInput->drawLine(l.at(0).x()*2, l.at(0).y()*2, l.at(l.count()-1).x()*2,l.at(l.count()-1).y()*2);
l = extractLine();
}
if (count)
k = k/count;
}
Lines CCAnalysis::getLines()
{
return lines;
}
qreal CCAnalysis::getK()
{
return k;
}
void CCAnalysis::rotatePhi(qreal phi, const QPoint &c, QPoint &p)
{
int x = p.x() - c.x();
int y = p.y() - c.y();
int x1 = x*cos(phi) - y*sin(phi);
int y1 = x*sin(phi) + y*cos(phi);
p.setX(x1+c.x());
p.setY(y1+c.y());
}
void CCAnalysis::addBarsHorizontal(int hoffset, int height, int woffset, int width)
{
bool * li = new bool[builder->height()];
if (height < 0) height = builder->height();
if (width < 0) width = builder->width();
for (int i = hoffset; i < height; i++)
li[i] = false;
foreach (TextLine tl, lines) {
if (tl.count() == 1) continue;
foreach(GlyphInfo gi, tl) // OPTIMIZE
if (_contains(woffset, width, gi.x)) {
for (int i = gi.y - gi.h/2; i < gi.y + gi.h/2; i++)
li[i] = true;
}
}
int him = 0;
int hlm = 0;
int lcount = 0;
int icount = 0;
int chl = 0;
int chi = 0;
for (int i= hoffset; i < height; i++) {
if (!li[i]) { // empty space
if (chl > 0) {
hlm += chl;
lcount++;
chl = 0;
}
chi++;
} else {
if (chi > 0) {
if (icount > 0)
him += chi;
icount++;
chi = 0;
}
chl++;
}
}
if ((icount < 3)||(lcount == 0)) {
delete[] li;
return;
}
him -= chi;
him = him/(icount-2);
hlm /= lcount;
int ilcount = 0;
int llcount = 0;
for (int i = hoffset; i < height; i++) {
if (!li[i]) {
ilcount++;
} else {
if (ilcount >= 5*him) {
Rect r;
r.x1 = woffset;
r.x2 = width-1;
r.y1 = 0;
for (int j = i - 3*him; j < i; j++) {
if ((!li[j-1]) && (!li[j]) && (!li[j+1])) {
r.y1 = j;
break;
}
}
if (r.y1 > 0) {
r.y2 = r.y1;
bars.append(r);
}
}
ilcount = 0;
llcount++;
}
}
delete[] li;
}
void CCAnalysis::addBarsHorisontalAfterVertical()
{
Rect r;
r.y1 = 0;
r.y2 = builder->height();
r.x1 = builder->width();
r.x2 = r.x1;
verts.append(r);
for (int i = 1; i < verts.count(); i++) {
addBarsHorizontal(0, -1, verts[i-1].x2, verts[i].x1);
}
}
/*void CCAnalysis::addBarsHorizontal()
{
bool * li = new bool[builder->height()];
for (int i = 0; i < builder->height(); i++)
li[i] = false;
int hlm = 0;
foreach (TextLine tl, lines)
hlm += tl.first().h;
hlm /= lines.count();
foreach (TextLine tl, lines) {
if (tl.count() < 3)
if (tl.first().x > lines.first().first().x + 64)
continue;
for (int i = (tl.first().y - hlm < 0 ? 0 : tl.first().y - hlm); i < (tl.last().y + hlm > builder->height() ? builder->height() : tl.last().y + hlm); i++)
li[i] = true;
//for (int i = (tl.last().y - tl.last().h < 0 ? 0 : tl.last().y - tl.last().h); i < (tl.last().y + tl.last().h > builder->height() ? builder->height() : tl.last().y + tl.last().h); i++)
// li[i] = true;
}
int fcount = 0;
for (int i = 0; i < builder->height(); i++) {
if (!li[i]) fcount++;
else {
if (fcount >= hlm*1.5) {
Rect r;
r.x1 = 0;
r.x2 = builder->width()-1;
r.y1 = i - hlm/2;
r.y2 = r.y1;
bars.append(r);
fcount = 0;
}
}
}
delete[] li;
}*/
void CCAnalysis::addBarsVertical()
{
int * li = new int[builder->width()];
for (int i = 0; i < builder->width(); i++)
li[i] = 0;
foreach(Rect c, components.values()) {
for (int j = c.x1; j <= c.x2; j++)
li[j]++;
}
int liprev = 1000;
for (int i = 0; i < builder->width(); i++)
{
if (li[i] < 3) {
if (liprev >= 3) {
Rect r;
r.x1 = i < builder->width() -5 ? i + 5 : i;
r.x2 = r.x1;
r.y1 = 0;
r.y2 = builder->height()-1;
bars.append(r);
verts.append(r);
}
} else
if (liprev < 3) {
Rect r;
r.x1 = i > 3 ? i - 3 : i-1;
r.x2 = r.x1;
r.y1 = 0;
r.y2 = builder->height()-1;
bars.append(r);
verts.append(r);
}
liprev = li[i];
}
delete[] li;
}
void CCAnalysis::rotateLines(qreal phi, const QPoint &c)
{
for (int i = 0; i < lines.count(); i++) {
TextLine l = lines.at(i);
for (int j =0; j < l.count(); j++) {
QPoint p = QPoint(l.at(j).x, l.at(j).y);
rotatePhi(phi, c, p);
ginfo g = l.at(j);
g.x = p.x();
g.y = p.y();
l.replace(j, g);
}
lines.replace(i, l);
}
}
int CCAnalysis::getMediumGlyphWidth()
{
return mediumGlyphWidth;
}
int CCAnalysis::getMediumGlyphHeight()
{
return mediumGlyphHeight;
}
ginfo::ginfo(int a1, int a2, int a3)
{
x = a1;
y = a2;
h = a3;
}
int CCAnalysis::getGlyphCount()
{
return glyphCount;
}
QList CCAnalysis::getGlyphs()
{
return components.values();
}
yagf-0.9.2.1/src/pdfextractor.h 0000664 0001750 0001750 00000004462 12247205425 017007 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2010 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef PDFEXTRACTOR_H
#define PDFEXTRACTOR_H
#include
#include
class PDFExtractor : public QObject
{
Q_OBJECT
public:
explicit PDFExtractor(QObject *parent = 0);
void setCommandStringPaged(const QString &cmdStr);
void setCommandStringEntire(const QString &cmdStr);
void setSourcePDF(const QString &value);
QString getSourcePDF();
void setOutputDir(const QString &value);
QString getOutputDir();
void setStartPage(const QString &value);
QString getStartPage();
void setStopPage(const QString &value);
QString getStopPage();
void setResolution(const QString &value);
QString getResolution();
void setOutputPrefix(const QString &value);
QString getOutputPrefix();
void setOutputExtension(const QString &value);
QString getOutputExtension();
void virtual exec() = 0;
static bool findProgram();
signals:
void terminate();
void killProcess();
void terminateProcess();
void addPage(QString pageName);
void finished();
public slots:
void cancel();
protected:
void execInternal(const QString &command, const QStringList &arguments);
private:
QString commandStringPaged;
QString commandStringEntire;
QString sourcePDF;
QString outputDir;
QString startPage;
QString stopPage;
QString resolution;
QString outputPrefix;
QString outputExtension;
int lastPage;
QStringList filters;
bool canceled;
};
#endif // PDFEXTRACTOR_H
yagf-0.9.2.1/src/qxtgraphicsview.h 0000664 0001750 0001750 00000002616 12247205425 017531 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef QXTGRAPHICSVIEW_H
#define QXTGRAPHICSVIEW_H
#include
#include
class QXtGraphicsView : public QGraphicsView
{
Q_OBJECT
public:
QXtGraphicsView(QWidget * parent = 0):QGraphicsView(parent)
{
connect(this, SIGNAL(scrolledDeferred()), this, SIGNAL(scrolled()), Qt::QueuedConnection);
}
void sendScrollSignal()
{
emit scrolledDeferred();
}
signals:
void scrolled();
void scrolledDeferred();
protected:
void scrollContentsBy (int dx, int dy)
{
QGraphicsView::scrollContentsBy(dx, dy);
emit scrolled();
}
};
#endif // QXTGRAPHICSVIEW_H
yagf-0.9.2.1/src/advancedconfigdialog.cpp 0000664 0001750 0001750 00000002413 12250140707 020735 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2013 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "advancedconfigdialog.h"
#include "ui_advancedconfigdialog.h"
AdvancedConfigDialog::AdvancedConfigDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AdvancedConfigDialog)
{
ui->setupUi(this);
}
AdvancedConfigDialog::~AdvancedConfigDialog()
{
delete ui;
}
bool AdvancedConfigDialog::doCrop1()
{
return ui->checkBox->checkState() == Qt::Checked;
}
void AdvancedConfigDialog::setCrop1(const bool value)
{
ui->checkBox->setCheckState((value == true ? Qt::Checked : Qt::Unchecked)) ;
}
yagf-0.9.2.1/src/droplabel.h 0000664 0001750 0001750 00000002360 12247205425 016241 0 ustar parallels parallels /*
YAGF - cuneiform and tesseract OCR graphical front-ends
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifndef DROPLABEL_H
#define DROPLABEL_H
#include
class QListWidget;
class DropLabel : public QLabel
{
Q_OBJECT
public:
DropLabel(QWidget * parent = 0, Qt::WindowFlags f = 0);
void setListWidget(QListWidget * w);
signals:
void pageRemoved(int id);
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);
void dropEvent(QDropEvent *event);
private:
QListWidget * lw;
};
#endif // DROPLABEL_H
yagf-0.9.2.1/src/mainform.ui 0000775 0001750 0001750 00000113240 12247205425 016276 0 ustar parallels parallels
MainWindow0019201138Qt::CustomContextMenuMainWindow:/yagf.png:/yagf.png22QFrame::StyledPanelQFrame::Raised1280128167772159494949494942552552551Qt::ScrollBarAlwaysOfftrue100128Qt::ElideNoneQListView::LeftToRight4QListView::IconMode1288012880767676949494949494606060949494767676949494949494949494949494767676949494949494606060949494767676949494949494949494949494949494949494949494949494949494949494949494949494949494949494:/images/trashcan_full.pngQt::AlignCenter10Qt::HorizontalQt::NoContextMenuTimes New Roman00192025&File&Help&Settings0000toolBar4848TopToolBarAreafalsetoolBar_2TopToolBarAreafalse:/images/scanner48.png:/images/scanner48.pngS&can...Scanning images using XSane...Ctrl+N:/images/document_save_as.png:/images/document_save_as.png&Save text...Ctrl+S:/images/document_open.png:/images/document_open.png&Open Image...Open ImageCtrl+O:/images/filefind.png:/images/filefind.png&RecognizeRecognizing text...Ctrl+RChoose &LanguageQuitCtrl+Q:/images/back.png:/images/back.pngPrevious pageMove to previous image:/images/forward.png:/images/forward.pngNext pageMove to next imageOnline HelpAbout...Online Help:/images/editcopy.png:/images/editcopy.pngCopy To ClipboardCopy recognized text to clipboard:/batch.png:/batch.pngRecognize &All PagesRecognize All PagesCtrl+A:/images/clearblocks.png:/images/clearblocks.pngClear all blocksClear all blocks:/images/trashcan2-s.png:/images/trashcan2-s.pngDelete the current blockDelete the current block:/images/recblocks.png:/images/recblocks.pngRecognize blockRecognize this blockClear numbersCrear block numberingtrue:/images/check_spelling.png:/images/check_spelling.pngCheck spelling:/images/savpicas.png:/images/savpicas.pngSave current image...Save currently opened image in its real size:/images/saveblock.png:/images/saveblock.pngSave blockSave the current block to the image file:/images/deskew2.png:/images/deskew2.pngDeskewCorrect the page skew true:/images/stock_new_html.png:/images/stock_new_html.pngSelect HTML formatSelect HTML format as recognition output:/images/larger.png:/images/larger.pngLarger viewLarger view:/images/smaller.png:/images/smaller.pngSmaller viewSmaller view:/images/rccw.png:/images/rccw.pngRotate 90 CCWRotate 90 CCW:/images/revert.png:/images/revert.pngRotate 180Rotate 180:/images/rcw.png:/images/rcw.pngRotate 90 CWRotate 90 CW<<Hide/Show Toolbar:/images/application_pdf.png:/images/application_pdf.pngImport from PDF...Import pages from PDF documentsOCR SettingsSet up the OCR parameters:/images/edit_paste.png:/images/edit_paste.pngPaste ImagePaste image from clipboard:/images/selecttext.png:/images/selecttext.pngSelect Text AreaSelect Text AreaDeskew BlockDeskew the current blockAdvanced SettingsThe settings you should probably never change:/images/selectmulti.png:/images/selectmulti.pngselect multiple blocksSplits text into several blocksToggle Large/Small Icons:/images/system_config_language.png:/images/system_config_language.pngSelect Recognition LanguageSelect Recognition Language:/images/tools_wizard_small.png:/images/tools_wizard_small.pngPrepare PagePrepare the page for recognitionSave Project...Load Project...QXtGraphicsViewQGraphicsViewqxtgraphicsview.hSideBarQListWidgetsidebar.hDropLabelQLabeldroplabel.hTextEditorQTextEdittexteditor.hactionTBLVtriggered()MainWindowenlargeButtonClicked()-1-1959568actionSmaller_viewtriggered()MainWindowdecreaseButtonClicked()-1-1959568actionRotate_90_CCWtriggered()MainWindowrotateCCWButtonClicked()-1-1959568actionRotate_180triggered()MainWindowrotate180ButtonClicked()-1-1959568actionRotate_90_CWtriggered()MainWindowrotateCWButtonClicked()-1-1959568actionHideShowTolbartriggered()MainWindowhideToolBar()-1-1959568actionImport_from_PDFtriggered()MainWindowimportPDF()-1-1959568actionOCR_Settingstriggered()MainWindowshowConfigDlg()-1-1959568actionPaste_Imagetriggered()MainWindowpasteimage()-1-1959568actionSelect_Text_Areatriggered()MainWindowselectTextArea()-1-1959568actionDeskew_by_Blocktriggered()MainWindowdeskewByBlock()-1-1959568actionAdvanced_Settingstriggered()MainWindowshowAdvancedSettings()-1-1959568actionSelect_multiple_blockstriggered()MainWindowselectBlocks()-1-1959568actionToggle_Large_Small_Iconstriggered()MainWindowsetSmallIcons()-1-1959568actionPrepare_Pagetriggered()MainWindowpreprocessPage()-1-1959568actionSave_Projecttriggered()MainWindowsaveProject()-1-1959568actionLoad_Projecttriggered()MainWindowloadProject()-1-1959568rotateCWButtonClicked()rotateCCWButtonClicked()rotate180ButtonClicked()enlargeButtonClicked()decreaseButtonClicked()hideToolBar()importPDF()showConfigDlg()pasteimage()blockAllText()deskewByBlock()showAdvancedSettings()selectTextArea()selectBlocks()setSmallIcons()preprocessPage()saveProject()loadProject()
yagf-0.9.2.1/src/qxtunixscinternal.h 0000664 0001750 0001750 00000001636 12247205425 020105 0 ustar parallels parallels /*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#ifndef QXTUNIXSCINTERNAL_H
#define QXTUNIXSCINTERNAL_H
#include
class QXtUnixSignalCatcherInternal : public QObject
{
Q_OBJECT
public:
QXtUnixSignalCatcherInternal(QObject *parent = 0) :
QObject(parent) {}
void emitSignal(int sig_num)
{
emit unixSignalInternal(sig_num);
}
signals:
void unixSignalInternal(int sig_num);
};
#endif // QXTUNIXSCINTERNAL_H
yagf-0.9.2.1/src/qxtgraphicsproxywidget.cpp 0000664 0001750 0001750 00000003306 12247205425 021474 0 ustar parallels parallels /*
YAGF - cuneiform OCR graphical front-end
Copyright (C) 2009-2011 Andrei Borovsky
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "qxtgraphicsproxywidget.h"
#include "qxtgraphicsview.h"
#include
#include
#include
QXtGraphicsProxyWidget::QXtGraphicsProxyWidget(QGraphicsItem * parent, Qt::WindowFlags wFlags) : QGraphicsProxyWidget(parent, wFlags)
{
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
}
void QXtGraphicsProxyWidget::setView(QXtGraphicsView * view)
{
mview = view;
QPointF p = mview->mapToScene(0,0);
setPos(p.x(), p.y());
//setPos(0,0);
connect(mview, SIGNAL(scrolled()), this, SLOT(viewScrolled()));
}
void QXtGraphicsProxyWidget::viewScrolled()
{
QPointF p = mview->mapToScene(0,0);
setPos(p.x(), p.y());
}
QVariant QXtGraphicsProxyWidget::itemChange(GraphicsItemChange change, const QVariant & value)
{
QVariant v;
matrix().reset();
if (change == QGraphicsItem::ItemTransformChange) {
v = QVariant(matrix());
return v;
}
return value;
}
yagf-0.9.2.1/src/images/ 0000775 0001750 0001750 00000000000 12250673444 015374 5 ustar parallels parallels yagf-0.9.2.1/src/images/application_pdf.png 0000664 0001750 0001750 00000020246 12247205425 021236 0 ustar parallels parallels PNG
IHDR >a tIME #3I~$ bKGD HIDATx tǫXE+"PPQHbrCmjUb=
V+nmhʎ"&[YBCIH'aw
7maB@{ofW+l)ʣQKj:Ւf5ZB83F%XpIpi-8H<:(vױcha:qDܿF>ݘ/2y46"K!X؉PEEbMEPRM%ʨLU9
iV0UTY&|GG>P~WYU*j[Uo&?Єc7j_uAi w .mi ?FW<,HK%x)@@nG7 >~Kp!)a }$@=xs z{Pn
#MD
BӒhFOT g$x[
ۋGc[`P o(7EO>IӧS0+Kַq#m=fkG3/87QKtOT
Ȳw@!ק>422,C=TMK9jݚFU.CWqv^B,kGM eU?-xU!>K{O[8* {-AE&}qVe@1#Њ?!|JF_k-ؑ^pXx5KW%7Tep#<.!@B>uxG?"^oV1^J${qa[mB!@GOM oUdμZީ[Je={l7kUiʣ5c~s._^uہW31ch@M7>=vQ
@l0Q*s1Cɻߟ|*qoUWpݿKie˴Ўk
^Iq!b{nl Ћ ߈lD;ޛq7Y;8pz}
`zfom(/)9Y8%H3{.-Coy7^o,'Lo Ru{9cM a>FÇm|hY/XY~V{YF-eX*ްA7_*BXE-d~@,^۴`ڕ|>Sqݻr6o6sH^qp̼ oFj<9KL֕כ
6AB'#bųaF>2 3#GՔ dϮÀ>Z;87p=i%@jvߍ `3Fidջql>#j#.eg =gэ7Wּ$ʛ=-6sP2@
|NdZ
Y&zA7 6hF#@$ɞSm$0 ,oK4,̙5:`°J@7
@+ÑCD;ەw~K|Z|;W_yŶ6QAjj&BDES43vGkw!gK.
94oѴYBvp2iW#c;*tMI|5˙>=>Z-e#/Zޞ֫f [*|Q
2}I0tOKm><:|.r'L/o Һtfxy;&1c;jkuF)yO@c__cX:i>et kcF1 c5|2o Ah?|oψ
ݻm%nrwqc$LBٴG
^7y'U{c|QTtc?"5-gupuub9p_|Ex,7Gsg
Ν6qi#
Fct"l.