feat(工程建立): OCR文字识别工程建立

no

Log: no
Change-Id: I6bb42a4ae96f000a1ee937d2c69d1f7e3208e7e3
This commit is contained in:
He MingYang
2021-06-10 18:54:54 +08:00
committed by hemingyang
parent 6e5f39162a
commit 155256cbd9
88 changed files with 5685 additions and 0 deletions

102
src/main.cpp Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "ocrapplication.h"
#include "service/ocrinterface.h"
#include "service/dbusocr_adaptor.h"
#include <DWidget>
#include <DLog>
#include <DWindowManagerHelper>
#include <DWidgetUtil>
#include <DGuiApplicationHelper>
#include <DApplication>
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusInterface>
DWIDGET_USE_NAMESPACE
int main(int argc, char *argv[])
{
if (argc < 2) {
qDebug() << "Cant open a null file";
return 0;
}
DGuiApplicationHelper::setUseInactiveColorGroup(false);
#if(DTK_VERSION < DTK_VERSION_CHECK(5,4,0,0))
DApplication::loadDXcbPlugin();
QScopedPointer<DApplication> app(new DApplication(argc, argv));
#else
QScopedPointer<DApplication> app(DApplication::globalApplication(argc,argv));
#endif
app->setOrganizationName("deepin");
app->setApplicationName("deepin-ocr");
app->setApplicationVersion("1.0");
Dtk::Core::DLogManager::registerConsoleAppender();
Dtk::Core::DLogManager::registerFileAppender();
QCommandLineOption dbusOption(QStringList() << "u" << "dbus", "Start from dbus.");
QCommandLineParser cmdParser;
cmdParser.setApplicationDescription("deepin-Ocr");
cmdParser.addHelpOption();
cmdParser.addVersionOption();
cmdParser.addOption(dbusOption);
cmdParser.process(*app);
app->loadTranslator();
OcrApplication instance;
QDBusConnection dbus = QDBusConnection::sessionBus();
if (dbus.registerService("com.deepin.Ocr")) {
// 第一次启动
// 注册Dbus服务和对象
dbus.registerObject("/com/deepin/Ocr", &instance);
// 初始化适配器
new DbusOcrAdaptor(&instance);
if (cmdParser.isSet(dbusOption)) {
// 第一调用已 --dbus参数启动
qDebug() << "dbus register waiting!";
return app->exec();
}
instance.openFile(QString(argv[1]));
} else {
// 第二次运行此应用,
// 调用DBus接口处理交给第一次调用的进程
// 本进程退退出
OcrInterface *pOcr = new OcrInterface("com.deepin.Ocr","/com/deepin/Ocr", QDBusConnection::sessionBus(), &instance);
qDebug() << __FUNCTION__ << __LINE__;
pOcr->openFile(QString(argv[1]));
//pOcr->openImage(QImage(QSize(500, 145), QImage::Format_RGB32));
return 0;
}
return app->exec();
}

315
src/mainwidget.cpp Normal file
View File

@ -0,0 +1,315 @@
#include "mainwidget.h"
#include "view/imageview.h"
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QTextBlock>
#include <QStandardPaths>
#include <QFileDialog>
#include <QFileInfo>
#include <DGuiApplicationHelper>
#include <DMainWindow>
#include <DTitlebar>
#include <DMessageManager>
#define App (static_cast<QApplication*>(QCoreApplication::instance()))
MainWidget::MainWidget(QWidget *parent) :
DWidget(parent)
{
setupUi(this);
DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType();
setIcons(themeType);
setupConnect();
}
MainWidget::~MainWidget()
{
// m_mainGridLayout->addLayout(m_buttonHorizontalLayout, 1, 0, 1, 1);
m_mainGridLayout->removeItem(m_buttonHorizontalLayout);
if (m_imageview) {
m_imageview->deleteLater();
m_imageview = nullptr;
}
if (m_mainGridLayout) {
m_mainGridLayout->deleteLater();
m_mainGridLayout = nullptr;
}
if (m_horizontalLayout) {
m_horizontalLayout->deleteLater();
m_horizontalLayout = nullptr;
}
if (m_plainTextEdit) {
m_plainTextEdit->deleteLater();
m_plainTextEdit = nullptr;
}
if (m_buttonHorizontalLayout) {
m_buttonHorizontalLayout->deleteLater();
m_buttonHorizontalLayout = nullptr;
}
if (m_tipHorizontalLayout) {
m_tipHorizontalLayout->deleteLater();
m_tipHorizontalLayout = nullptr;
}
if (m_tiplabel) {
m_tiplabel->deleteLater();
m_tiplabel = nullptr;
}
if (m_copyBtn) {
m_copyBtn->deleteLater();
m_copyBtn = nullptr;
}
if (m_exportBtn) {
m_exportBtn->deleteLater();
m_exportBtn = nullptr;
}
if (m_tipIconLabel) {
m_tipIconLabel->deleteLater();
m_tipIconLabel = nullptr;
}
}
void MainWidget::setupUi(QWidget *Widget)
{
DMainWindow *mainWindow = static_cast<DMainWindow *>(this->parent());
if (mainWindow) {
mainWindow->titlebar()->setMenuVisible(false);
}
m_mainGridLayout = new QGridLayout(Widget);
m_mainGridLayout->setSpacing(6);
m_mainGridLayout->setContentsMargins(0, 0, 0, 0);
m_mainGridLayout->setObjectName(QStringLiteral("gridLayout"));
m_horizontalLayout = new QHBoxLayout(Widget);
m_horizontalLayout->setSpacing(0);
m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
m_plainTextEdit = new ResultTextView(Widget);
m_plainTextEdit->setObjectName(QStringLiteral("plainTextEdit"));
if (!m_imageview) {
m_imageview = new ImageView();
}
m_horizontalLayout->addWidget(m_imageview);
m_horizontalLayout->addWidget(m_plainTextEdit);
m_horizontalLayout->setStretch(0, 1);
m_mainGridLayout->addLayout(m_horizontalLayout, 0, 0, 1, 1);
m_mainGridLayout->setColumnStretch(0, 1);
m_buttonHorizontalLayout = new QHBoxLayout(Widget);
m_buttonHorizontalLayout->setContentsMargins(20, 0, 59, 0); //表示控件与窗体的左右边距
// m_buttonHorizontalLayout->setSpacing(30);
m_buttonHorizontalLayout->setObjectName(QStringLiteral("horizontalLayout_2"));
m_tipHorizontalLayout = new QHBoxLayout(Widget);
m_tipIconLabel = new DLabel(Widget);
m_tipIconLabel->setObjectName(QStringLiteral("tipIconLabel"));
m_tipHorizontalLayout->addWidget(m_tipIconLabel);
m_tiplabel = new DLabel(Widget);
m_tiplabel->setObjectName(QStringLiteral("tiplabel"));
m_tipHorizontalLayout->addWidget(m_tiplabel);
m_buttonHorizontalLayout->addLayout(m_tipHorizontalLayout);
QSpacerItem *horizontalSpacer = new QSpacerItem(159, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); m_buttonHorizontalLayout->addItem(horizontalSpacer);
m_buttonHorizontalLayout->addItem(horizontalSpacer);
m_copyBtn = new DIconButton(Widget);
m_copyBtn->setObjectName(QStringLiteral("Copy"));
m_copyBtn->setMaximumSize(QSize(40, 40));
m_buttonHorizontalLayout->addWidget(m_copyBtn);
m_exportBtn = new DIconButton(Widget);
m_exportBtn->setObjectName(QStringLiteral("Export"));
m_exportBtn->setMaximumSize(QSize(40, 40));
m_buttonHorizontalLayout->addWidget(m_exportBtn);
m_mainGridLayout->addLayout(m_buttonHorizontalLayout, 1, 0, 1, 1);
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
m_pwidget = new QWidget(this);
m_pwidget->setFocusPolicy(Qt::NoFocus);
m_pwidget->setAttribute(Qt::WA_TransparentForMouseEvents);
m_pwidget->setFixedSize(this->width(), this->height() - 23);
m_pwidget->move(0, 0);
createLoadingUi();
// deleteLoadingUi();
}
void MainWidget::setupConnect()
{
connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::paletteTypeChanged, this, &MainWidget::setIcons);
connect(m_exportBtn, &DIconButton::clicked, this, &MainWidget::slotExport);
connect(m_copyBtn, &DIconButton::clicked, this, &MainWidget::slotCopy);
}
void MainWidget::retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "Widget", nullptr));
m_tiplabel->setText(QApplication::translate("Widget", "Tips: The clearer the image is, the more accurate the text is", nullptr));
// m_copyBtn->setText(QApplication::translate("Widget", "Copy", nullptr));
// m_exportBtn->setText(QApplication::translate("Widget", "Export", nullptr));
}
void MainWidget::createLoadingUi()
{
m_isLoading = true;
m_loadingWidget = new TextLoadWidget(this);
m_loadingWidget->resize(40, 40);
m_loadingWidget->show();
m_loadingTip = new DLabel(tr("Recognizing"), this);
m_loadingTip->show();
DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType();
if (themeType == DGuiApplicationHelper::DarkType) {
m_imageview->setForegroundBrush(QColor(0, 0, 0, 150)); //设置场景的前景色,类似于遮罩
} else {
m_imageview->setForegroundBrush(QColor(255, 255, 255, 150)); //设置场景的前景色,类似于遮罩
}
}
void MainWidget::deleteLoadingUi()
{
m_isLoading = false;
if (m_loadingWidget) {
m_loadingWidget->deleteLater();
m_loadingWidget = nullptr;
}
if (m_loadingTip) {
m_loadingTip->deleteLater();
m_loadingTip = nullptr;
}
m_imageview->setForegroundBrush(QColor(0, 0, 0, 0)); //设置场景的前景色,类似于遮罩
}
void MainWidget::loadingUi()
{
if (m_loadingWidget && m_loadingTip && m_plainTextEdit) {
int x = this->width() - m_plainTextEdit->width() / 2;
int y = this->height() / 2 - 50;
m_loadingWidget->move(x, y);
m_loadingTip->move(x - 20, y + 24);
}
}
void MainWidget::openImage(const QString &path)
{
QImage img(path);
m_imageview->openFilterImage(img);
m_imageview->fitWindow();
m_imgName = path;
}
void MainWidget::openImage(const QImage &img)
{
m_imageview->openFilterImage(img);
m_imageview->fitWindow();
m_imgName = "";
}
void MainWidget::resizeEvent(QResizeEvent *event)
{
loadingUi();
return DWidget::resizeEvent(event);
}
void MainWidget::slotCopy()
{
QIcon icon(":/assets/icon_toast_sucess_new.svg");
DFloatingMessage *pDFloatingMessage = new DFloatingMessage(DFloatingMessage::MessageType::TransientType, this);
pDFloatingMessage->setBlurBackgroundEnabled(true);
pDFloatingMessage->setMessage(tr("Copied"));
pDFloatingMessage->setIcon(icon);
pDFloatingMessage->raise();
DMessageManager::instance()->sendMessage(this, pDFloatingMessage);
m_plainTextEdit->copy();
}
void MainWidget::slotExport()
{
QStringList list = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
QString download = "";
if (list.size() > 0) {
download = list.at(0);
} else {
QStringList home = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
if (home.size() > 0) {
download = home.at(0) + "/Downloads";
}
}
QString fileName = QFileInfo(m_imgName).completeBaseName();
QString file_path = QFileDialog::getSaveFileName(this, "save as", download + "/" + fileName, "*.txt");
qDebug() << file_path;
QString path = file_path + ".txt";
QFile file(path);
if (file.open(QFile::WriteOnly | QFile::Text)) {
QTextStream out(&file);
out << m_plainTextEdit->document()->toPlainText();
}
}
void MainWidget::setIcons(DGuiApplicationHelper::ColorType themeType)
{
if (themeType == DGuiApplicationHelper::DarkType) {
m_tipIconLabel->setPixmap(QPixmap(":/assets/tip_dark.svg"));
m_tipIconLabel->setFixedSize(QSize(14, 14));
m_copyBtn->setIcon(QIcon(":/assets/copy_dark.svg"));
m_copyBtn->setIconSize(QSize(36, 36));
m_copyBtn->setFlat(true);
m_exportBtn->setIcon(QIcon(":/assets/download_dark.svg"));
m_exportBtn->setIconSize(QSize(36, 36));
m_exportBtn->setFlat(true);
App->setWindowIcon(QIcon(":/assets/appicon_dark.svg"));
DMainWindow *mainWindow = static_cast<DMainWindow *>(this->parent());
if (mainWindow) {
mainWindow->titlebar()->setIcon(QIcon(":/assets/appicon_dark.svg"));
}
if (m_isLoading) {
m_imageview->setForegroundBrush(QColor(0, 0, 0, 150)); //设置场景的前景色,类似于遮罩
}
} else {
m_tipIconLabel->setPixmap(QPixmap(":/assets/tip_light.svg"));
m_tipIconLabel->setFixedSize(QSize(14, 14));
m_copyBtn->setIcon(QIcon(":/assets/copy_light.svg"));
m_copyBtn->setIconSize(QSize(36, 36));
m_copyBtn->setFlat(true);
m_exportBtn->setIcon(QIcon(":/assets/download_light.svg"));
m_exportBtn->setIconSize(QSize(36, 36));
m_exportBtn->setFlat(true);
App->setWindowIcon(QIcon(":/assets/appicon_light.svg"));
DMainWindow *mainWindow = static_cast<DMainWindow *>(this->parent());
if (mainWindow) {
mainWindow->titlebar()->setIcon(QIcon(":/assets/appicon_light.svg"));
}
if (m_isLoading) {
m_imageview->setForegroundBrush(QColor(255, 255, 255, 150)); //设置场景的前景色,类似于遮罩
}
}
} // setupUi

66
src/mainwidget.h Normal file
View File

@ -0,0 +1,66 @@
#ifndef WIDGET_H
#define WIDGET_H
#include <DWidget>
#include <DIconButton>
#include <DPlainTextEdit>
#include <DLabel>
#include <DGuiApplicationHelper>
#include "resulttextview.h"
#include "textloadwidget.h"
class QGridLayout;
class QHBoxLayout;
class ImageView;
DWIDGET_USE_NAMESPACE
class MainWidget : public DWidget
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = nullptr);
~MainWidget();
void setupUi(QWidget *Widget);
void setupConnect();
void retranslateUi(QWidget *Widget);
void createLoadingUi();
void deleteLoadingUi();
void loadingUi();
void openImage(const QString &path);
void openImage(const QImage &img);
protected:
void resizeEvent(QResizeEvent *event);
private slots:
void setIcons(DGuiApplicationHelper::ColorType themeType);
void slotCopy();
void slotExport();
// void change()
private:
QGridLayout *m_mainGridLayout{nullptr};
QHBoxLayout *m_horizontalLayout{nullptr};
ResultTextView *m_plainTextEdit{nullptr};
QHBoxLayout *m_buttonHorizontalLayout{nullptr};
QHBoxLayout *m_tipHorizontalLayout{nullptr};
DLabel *m_tiplabel{nullptr};
DIconButton *m_copyBtn{nullptr};
DIconButton *m_exportBtn{nullptr};
ImageView *m_imageview{nullptr};
DLabel *m_tipIconLabel{nullptr};
QString m_imgName; //当前图片绝对路径
QWidget *m_pwidget{nullptr};
TextLoadWidget *m_loadingWidget{nullptr};
DLabel *m_loadingTip{nullptr};
bool m_isLoading{false};
};
#endif // WIDGET_H

55
src/mainwindow.cpp Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "mainwindow.h"
#include "mainwidget.h"
#include "service/dbusocr_adaptor.h"
#include <QLabel>
#include <QDBusConnection>
#include <DTitlebar>
MainWindow::MainWindow(QWidget *parent)
: DMainWindow(parent)
{
if (!m_mainWidget) {
m_mainWidget = new MainWidget(this);
}
this->setCentralWidget(m_mainWidget);
}
MainWindow::~MainWindow()
{
}
bool MainWindow::openFile(const QString &filePaths)
{
m_mainWidget->openImage(filePaths);
return true;
}
bool MainWindow::openImage(const QImage &image)
{
m_mainWidget->openImage(image);
return true;
}

44
src/mainwindow.h Normal file
View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <DMainWindow>
#include <QMainWindow>
class MainWidget;
DWIDGET_USE_NAMESPACE
class MainWindow : public DMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;
bool openFile(const QString &filePaths);
bool openImage(const QImage &image);
private:
MainWidget *m_mainWidget{nullptr};
};
#endif // MAINWINDOW_H

48
src/ocrapplication.cpp Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "ocrapplication.h"
#include "mainwindow.h"
OcrApplication::OcrApplication(QObject *parent) : QObject(parent)
{
}
bool OcrApplication::openFile(QString filePath)
{
qDebug() << __FUNCTION__ << __LINE__ << filePath;
MainWindow *win = new MainWindow();
win->openFile(filePath);
win->resize(800, 600);
win->show();
return true;
}
void OcrApplication::openImage(QImage image)
{
qDebug() << __FUNCTION__ << __LINE__ << image.size();
MainWindow *win = new MainWindow();
win->openImage(image);
win->resize(800, 600);
win->show();
}

47
src/ocrapplication.h Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef OCRAPPLICATION_H
#define OCRAPPLICATION_H
#include "mainwindow.h"
#include <QObject>
#include <QImage>
class OcrApplication : public QObject
{
Q_OBJECT
public:
explicit OcrApplication(QObject *parent = nullptr);
Q_INVOKABLE bool openFile(QString filePath);
Q_INVOKABLE void openImage(QImage image);
signals:
public slots:
};
#endif // OCRAPPLICATION_H

44
src/resulttextview.cpp Normal file
View File

@ -0,0 +1,44 @@
#include "resulttextview.h"
#include <QDebug>
ResultTextView::ResultTextView(QWidget *parent)
: m_Menu(nullptr), m_actCopy(nullptr), m_actCut(nullptr), m_actSelectAll(nullptr)
{
Q_UNUSED(parent)
m_Menu = new QMenu(this);
m_actCopy = new QAction(this);
m_actCopy->setText(tr("Copy"));
m_actCut = new QAction(this);
m_actCut->setText(tr("Cut"));
m_actSelectAll = new QAction(this);
m_actSelectAll->setText(tr("SelectAll"));
m_Menu->addAction(m_actSelectAll);
m_Menu->addAction(m_actCopy);
m_Menu->addAction(m_actCut);
connect(m_actSelectAll, &QAction::triggered, this, [ = ]() {
emit this->selectAll();
});
connect(m_actCopy, &QAction::triggered, this, [ = ]() {
emit this->copy();
});
connect(m_actCut, &QAction::triggered, this, [ = ]() {
emit this->cut();
});
}
void ResultTextView::contextMenuEvent(QContextMenuEvent *e)
{
Q_UNUSED(e)
//当前是否有选中文本
QString select_str = this->textCursor().selectedText();
if (select_str.length() < 1) {
m_actCopy->setEnabled(false);
m_actCut->setEnabled(false);
} else {
m_actCopy->setEnabled(true);
m_actCut->setEnabled(true);
}
m_Menu->exec(QCursor::pos());
}

27
src/resulttextview.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef RESULTTEXTVIEW_H
#define RESULTTEXTVIEW_H
#include <QObject>
#include <DPlainTextEdit>
#include <QAction>
#include <QMenu>
DWIDGET_USE_NAMESPACE
class ResultTextView : public DPlainTextEdit
{
Q_OBJECT
public:
explicit ResultTextView(QWidget *parent = nullptr);
protected:
void contextMenuEvent(QContextMenuEvent *e) override;
private:
QMenu *m_Menu;
QAction *m_actCopy;
QAction *m_actCut;
QAction *m_actSelectAll;
};
#endif // RESULTTEXTVIEW_H

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "dbusocr_adaptor.h"
#include <QtCore/QMetaObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QWidget>
#include <QDebug>
DbusOcrAdaptor::DbusOcrAdaptor(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
// constructor
setAutoRelaySignals(true);
}
DbusOcrAdaptor::~DbusOcrAdaptor()
{
// destructor
}
bool DbusOcrAdaptor::openFile(QString filePath)
{
qDebug() << __FUNCTION__ << __LINE__;
QMetaObject::invokeMethod(parent(), "openFile", Q_ARG(QString, filePath));
return true;
}
void DbusOcrAdaptor::openImage(QByteArray images)
{
qDebug() << __FUNCTION__ << __LINE__;
QByteArray data = images;
QString tmp_data = QString::fromLatin1(data.data(), data.size());
QByteArray srcData = QByteArray::fromBase64(tmp_data.toLatin1());
data = qUncompress(srcData);
QImage image;
image.loadFromData(data);
QMetaObject::invokeMethod(parent(), "openImage", Q_ARG(QImage, image));
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef DBUSOCR_ADAPTOR_H
#define DBUSOCR_ADAPTOR_H
#include <QtCore/QObject>
#include <QtDBus/QtDBus>
QT_BEGIN_NAMESPACE
class QByteArray;
template<class T> class QList;
template<class Key, class Value> class QMap;
class QString;
class QStringList;
class QVariant;
QT_END_NAMESPACE
/*
* @bref: dbusocr_adaptor 提供给外部程序调用的方法
*/
class DbusOcrAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "com.deepin.Ocr")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"com.deepin.Ocr\">\n"
" <method name=\"openImage\">\n"
" <arg direction=\"in\" type=\"ay\" name=\"openImage\"/>\n"
" </method>\n"
" <method name=\"openFile\">\n"
" <arg direction=\"in\" type=\"s\" name=\"openFile\"/>\n"
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" </interface>\n")
public:
explicit DbusOcrAdaptor(QObject *parent);
virtual ~DbusOcrAdaptor();
public Q_SLOTS: // METHODS
void openImage(QByteArray images);
bool openFile(QString filePath);
Q_SIGNALS: // SIGNALS
};
#endif // DBUSDRAW_ADAPTOR_H

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#include "ocrinterface.h"
#include <QDBusMetaType>
OcrInterface::OcrInterface(const QString &serviceName, const QString &ObjectPath,
const QDBusConnection &connection, QObject *parent)
: QDBusAbstractInterface(serviceName, ObjectPath, staticInterfaceName(), connection, parent)
{
}
OcrInterface::~OcrInterface()
{
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2020 ~ 2021 Deepin Technology Co., Ltd.
*
* Author: He MingYang Hao<hemingyang@uniontech.com>
*
* Maintainer: He MingYang <hemingyang@uniontech.com>
*
* 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
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef OCRINTERFACE_H
#define OCRINTERFACE_H
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QtDBus/QtDBus>
#include <QImage>
#include <QBuffer>
#include <QDebug>
class OcrInterface: public QDBusAbstractInterface
{
Q_OBJECT
public:
static inline const char *staticInterfaceName()
{
return "com.deepin.Ocr";
}
public:
/*
* @param: serviceName QDBusConnection 注册的服务名字
* @param: ObjectPath QDBusConnection 注册的对象路径
*/
OcrInterface(const QString &serviceName, const QString &ObjectPath,
const QDBusConnection &connection, QObject *parent = nullptr);
QDBusConnection dbus = QDBusConnection::sessionBus();
~OcrInterface();
public Q_SLOTS: // METHODS
/*
* @bref:openFile 通过路径打开图片文件
* @param: filePath 图片的路径
* @return: QDBusPendingReply
*/
inline QDBusPendingReply<> openFile(const QString &filePath)
{
return call(QStringLiteral("openFile"), filePath);
}
/*
* @bref:openImages
* @param: image 图片
* @return: QDBusPendingReply
* @note:
*/
inline QDBusPendingReply<> openImage(const QImage &image)
{
qDebug() << __FUNCTION__;
QByteArray data;
QBuffer buf(&data);
if (image.save(&buf, "PNG")) {
data = qCompress(data, 9);
data = data.toBase64();
}
return call(QStringLiteral("openImage"), QVariant::fromValue(data));
}
Q_SIGNALS: // SIGNALS
};
namespace com {
namespace deepin {
typedef ::OcrInterface Ocr;
}
}
#endif // DRAWINTERFACE_H

13
src/textloadwidget.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "textloadwidget.h"
#include <QVBoxLayout>
TextLoadWidget::TextLoadWidget(DWidget *parent)
: DWidget(parent)
{
this->setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground, true);
m_spinner = new DSpinner(this);
m_spinner->start();
m_spinner->setFixedSize(24, 24);
m_spinner->show();
}

22
src/textloadwidget.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef TEXTLOADWIDGET_H
#define TEXTLOADWIDGET_H
#include <DWidget>
#include <DSpinner>
#include <DLabel>
DWIDGET_USE_NAMESPACE
class QVBoxLayout;
class TextLoadWidget : public DWidget
{
Q_OBJECT
public:
TextLoadWidget(DWidget *parent = nullptr);
private :
DSpinner *m_spinner{nullptr};
QVBoxLayout *m_vboxLayout{nullptr};
DLabel *m_label{nullptr};
};
#endif // TEXTLOADWIDGET_H

278
src/view/imageview.cpp Normal file
View File

@ -0,0 +1,278 @@
#include "imageview.h"
#include <QPaintDevice>
#include <QGraphicsPixmapItem>
#include <QDebug>
#include <QDragEnterEvent>
#include <QMimeData>
#include <QFileDialog>
#include <QMessageBox>
#include <QThreadPool>
#include <qmath.h>
#include <QObject>
const qreal MAX_SCALE_FACTOR = 20.0;
const qreal MIN_SCALE_FACTOR = 0.029;
#define devicePixelRatioF devicePixelRatio
ImageView::ImageView(QWidget *parent):
QGraphicsView(parent)
{
setMouseTracking(true);
setDragMode(ScrollHandDrag);
QGraphicsScene *scene = new QGraphicsScene(this);
setScene(scene);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}
void ImageView::openImage(const QString &path)
{
if (scene()) {
if (m_currentImage) {
delete m_currentImage;
m_currentImage = nullptr;
}
m_currentImage = new QImage(path);
if (!m_currentImage->isNull()) {
QPixmap pic = QPixmap::fromImage(*m_currentImage);
scene()->clear();
m_pixmapItem = new QGraphicsPixmapItem(pic);
m_pixmapItem->setTransformationMode(Qt::SmoothTransformation);
QRectF rect = m_pixmapItem->boundingRect();
setSceneRect(rect);
scene()->addItem(m_pixmapItem);
fitWindow();
m_currentPath = path;
} else {
// App->setStackWidget(0);
}
m_FilterImage = image();
}
}
void ImageView::openFilterImage(QImage img)
{
if (!img.isNull() && scene()) {
m_FilterImage = img;
}
QPixmap pic = QPixmap::fromImage(img);
if (!pic.isNull()) {
scene()->clear();
m_pixmapItem = new QGraphicsPixmapItem(pic);
m_pixmapItem->setTransformationMode(Qt::SmoothTransformation);
QRectF rect = m_pixmapItem->boundingRect();
setSceneRect(rect);
scene()->addItem(m_pixmapItem);
fitWindow();
}
}
qreal ImageView::windowRelativeScale() const
{
QRectF bf = sceneRect();
if (this->window()->isFullScreen()) {
if (1.0 * (width()) / (height() + 15) > 1.0 * bf.width() / bf.height()) {
return 1.0 * (height() + 15) / bf.height();
} else {
return 1.0 * (width()) / bf.width();
}
} else {
if (1.0 * (width() - 20) / (height() - 180) > 1.0 * bf.width() / bf.height()) {
return 1.0 * (height() - 180) / bf.height();
} else {
return 1.0 * (width() - 20) / bf.width();
}
}
}
void ImageView::fitWindow()
{
qreal wrs = windowRelativeScale();
m_scal = wrs;
resetTransform();
scale(wrs, wrs);
// if (wrs - 1 > -0.01 && wrs - 1 < 0.01) {
// emit checkAdaptImageBtn();
// } else {
// emit disCheckAdaptImageBtn();
// }
m_isFitImage = false;
m_isFitWindow = true;
}
void ImageView::fitImage()
{
resetTransform();
m_scal = 1.0;
scale(1, 1);
m_isFitImage = true;
m_isFitWindow = false;
}
void ImageView::RotateImage(const int &index)
{
if (!m_pixmapItem && scene()) return;
QPixmap pixmap = m_pixmapItem->pixmap();
QMatrix rotate;
rotate.rotate(index);
pixmap = pixmap.transformed(rotate, Qt::FastTransformation);
pixmap.setDevicePixelRatio(devicePixelRatioF());
scene()->clear();
resetTransform();
m_pixmapItem = new QGraphicsPixmapItem(pixmap);
m_pixmapItem->setTransformationMode(Qt::SmoothTransformation);
// Make sure item show in center of view after reload
QRectF rect = m_pixmapItem->boundingRect();
setSceneRect(rect);
scene()->addItem(m_pixmapItem);
autoFit();
m_rotateAngel += index;
m_FilterImage = image();
}
void ImageView::savecurrentPic()
{
QString filename = QFileDialog::getSaveFileName(this, tr("Save Image"), "", tr("Images (*.png *.bmp *.jpg)")); //选择路径
image().save(filename);
}
void ImageView::savecurrentPicAs()
{
QFileDialog fileDialog;
QString fileName = fileDialog.getSaveFileName(this, tr("Open File"), "/home", tr("png"));
if (fileName == "") {
return;
}
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("error"), tr("open file error"));
return;
} else {
image().save(fileName, "png");
}
}
void ImageView::openImage(QImage *img)
{
if (!img->isNull() && scene()) {
QPixmap pic = QPixmap::fromImage(*img);
if (!pic.isNull()) {
scene()->clear();
m_pixmapItem = new QGraphicsPixmapItem(pic);
m_pixmapItem->setTransformationMode(Qt::SmoothTransformation);
QRectF rect = m_pixmapItem->boundingRect();
setSceneRect(rect);
scene()->addItem(m_pixmapItem);
fitWindow();
}
}
}
qreal ImageView::imageRelativeScale() const
{
return transform().m11() / devicePixelRatioF();
}
void ImageView::autoFit()
{
if (image().isNull())
return;
QSize image_size = image().size();
// change some code in graphicsitem.cpp line100.
if ((image_size.width() >= width() || image_size.height() >= height() - 150) && width() > 0 &&
height() > 0) {
fitWindow();
} else {
fitImage();
}
}
void ImageView::mouseMoveEvent(QMouseEvent *event)
{
return QGraphicsView::mouseMoveEvent(event);
}
const QImage ImageView::image()
{
if (m_pixmapItem) {
return m_pixmapItem->pixmap().toImage();
} else {
return QImage();
}
}
void ImageView::resizeEvent(QResizeEvent *event)
{
return QGraphicsView::resizeEvent(event);
}
void ImageView::wheelEvent(QWheelEvent *event)
{
qreal factor = qPow(1.2, event->delta() / 240.0);
scaleAtPoint(event->pos(), factor);
event->accept();
}
void ImageView::scaleAtPoint(QPoint pos, qreal factor)
{
// Remember zoom anchor point.
const QPointF targetPos = pos;
const QPointF targetScenePos = mapToScene(targetPos.toPoint());
// Do the scaling.
setScaleValue(factor);
// Restore the zoom anchor point.
//
// The Basic idea here is we don't care how the scene is scaled or transformed,
// we just want to restore the anchor point to the target position we've
// remembered, in the coordinate of the view/viewport.
const QPointF curPos = mapFromScene(targetScenePos);
const QPointF centerPos = QPointF(width() / 2.0, height() / 2.0) + (curPos - targetPos);
const QPointF centerScenePos = mapToScene(centerPos.toPoint());
centerOn(static_cast<int>(centerScenePos.x()), static_cast<int>(centerScenePos.y()));
}
void ImageView::setScaleValue(qreal v)
{
//由于矩阵被旋转,通过矩阵获取缩放因子,计算缩放比例错误,因此记录过程中的缩放因子来判断缩放比例
m_scal *= v;
qDebug() << m_scal;
scale(v, v);
//const qreal irs = imageRelativeScale() * devicePixelRatioF();
// Rollback
if (v < 1 && /*irs <= MIN_SCALE_FACTOR)*/m_scal < 0.03) {
const qreal minv = MIN_SCALE_FACTOR / m_scal;
// if (minv < 1.09) return;
scale(minv, minv);
m_scal *= minv;
} else if (v > 1 && /*irs >= MAX_SCALE_FACTOR*/m_scal > 20) {
const qreal maxv = MAX_SCALE_FACTOR / m_scal;
scale(maxv, maxv);
m_scal *= maxv;
} else {
m_isFitImage = false;
m_isFitWindow = false;
}
// qreal rescale = imageRelativeScale() * devicePixelRatioF();
// if (rescale - 1 > -0.01 && rescale - 1 < 0.01) {
// emit checkAdaptImageBtn();
// } else {
// emit disCheckAdaptImageBtn();
// }
}

68
src/view/imageview.h Normal file
View File

@ -0,0 +1,68 @@
/*
*图像显示界面
*/
#ifndef IMAGEVIEW_H
#define IMAGEVIEW_H
#include <QGraphicsView>
class QGraphicsPixmapItem;
class ImageView : public QGraphicsView
{
Q_OBJECT
public:
ImageView(QWidget *parent = nullptr);
//通过路径打开图片
void openImage(const QString &path);
//用于鼠标滚轮滑动
qreal windowRelativeScale() const;
qreal imageRelativeScale() const;
void scaleAtPoint(QPoint pos, qreal factor);
void setScaleValue(qreal v);
//自适应窗口
void autoFit();
//鼠标移动事件
void mouseMoveEvent(QMouseEvent *event) override;
//返回当前图片img
const QImage image();
void openFilterImage(QImage img);
public slots:
//适应窗口大小
void fitWindow();
//适应图片大小
void fitImage();
//旋转图片感觉index角度-为左,+为右
void RotateImage(const int &index);
//保存图片
void savecurrentPic();
//另存为
void savecurrentPicAs();
//打开该图片
void openImage(QImage *img);
//窗口大小改变事件
void resizeEvent(QResizeEvent *event) override;
//鼠标滚轮事件
void wheelEvent(QWheelEvent *event) override;
protected:
private:
QString m_currentPath;//当前图片路径
QGraphicsPixmapItem *m_pixmapItem{nullptr};//当前图像的item
bool m_isFitImage = false;//是否适应图片
bool m_isFitWindow = false;//是否适应窗口
qreal m_scal = 1.0;
int m_rotateAngel = 0; //旋转角度
QImage *m_currentImage{nullptr};//当前原始图像
QImage m_FilterImage{nullptr};//当前处理的图像
QImage m_lightContrastImage{nullptr};//亮度曝光度图像
};
#endif // IMAGEVIEW_H