Add a huge performance improvement when using the pencil

This commit is contained in:
lupoDharkael
2017-05-21 18:19:25 +02:00
parent d849e9dbf5
commit 087cb0a6f8
5 changed files with 140 additions and 70 deletions

View File

@@ -81,7 +81,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) :
m_buttonHandler->hide();
// init screenshot
createCapture();
resize(m_screenshot.size());
resize(m_screenshot->getScreenshot().size());
// init interface color
m_uiColor = QSettings().value("uiColor").value<QColor>();
show();
@@ -91,6 +91,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) :
CaptureWidget::~CaptureWidget() {
delete(m_buttonHandler);
delete(m_screenshot);
}
// redefineButtons retrieves the buttons configured to be shown with the
@@ -122,10 +123,15 @@ void CaptureWidget::paintEvent(QPaintEvent *) {
if (m_grabbing) { // grabWindow() should just get the background
return;
}
Screenshot s(m_screenshot);
s.paintModifications(m_modifications);
painter.drawPixmap(0, 0, s.getScreenshot());
// if we are creating a new modification to the screenshot we just draw
// a temporal modification without antialiasing in the pencil tool for
// performance. When we are not drawing we just shot the modified screenshot
if (m_mouseIsClicked && m_state != Button::Type::move) {
painter.drawPixmap(0, 0, m_screenshot->paintTemporalModification(
m_modifications.last()));
} else {
painter.drawPixmap(0, 0, m_screenshot->getScreenshot());
}
QColor overlayColor(0, 0, 0, 160);
painter.setBrush(overlayColor);
@@ -166,6 +172,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) {
if (m_state != Button::Type::move) {
m_modifications.append(CaptureModification(m_state, e->pos(),
m_colorPicker->getDrawColor()));
m_screenshot->paintModification(m_modifications.last());
return;
}
m_dragStartPoint = e->pos();
@@ -293,6 +300,10 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) {
m_colorPicker->hide();
m_rightClick = false;
return;
// when we end the drawing of a modification in the capture we have to
// register the last point and add the whole modification to the screenshot
} else if (m_mouseIsClicked && m_state != Button::Type::move) {
m_screenshot->paintModification(m_modifications.last());
}
if (!m_selection.isNull() && !m_buttonHandler->isVisible()) {
@@ -335,22 +346,18 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) {
}
void CaptureWidget::saveScreenshot() {
Screenshot s(m_screenshot);
s.paintModifications(m_modifications);
if (m_selection.isNull()) {
s.graphicalSave();
m_screenshot->graphicalSave();
} else { // save full screen when no selection
s.graphicalSave(getExtendedSelection());
m_screenshot->graphicalSave(getExtendedSelection());
}
}
void CaptureWidget::copyScreenshot() {
Screenshot s(m_screenshot);
s.paintModifications(m_modifications);
if (m_selection.isNull()) {
QApplication::clipboard()->setPixmap(s.getScreenshot());
QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot());
} else { // copy full screen when no selection
QApplication::clipboard()->setPixmap(s.getScreenshot()
QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot()
.copy(getExtendedSelection()));
}
close();
@@ -367,15 +374,13 @@ void CaptureWidget::openURL(QNetworkReply *reply) {
}
void CaptureWidget::uploadScreenshot() {
Screenshot s(m_screenshot);
s.paintModifications(m_modifications);
QNetworkAccessManager *am = new QNetworkAccessManager(this);
connect(am, &QNetworkAccessManager::finished, this,
&CaptureWidget::openURL);
if (m_selection.isNull()) {
s.uploadToImgur(am);
m_screenshot->uploadToImgur(am);
} else {
s.uploadToImgur(am, getExtendedSelection());
m_screenshot->uploadToImgur(am, getExtendedSelection());
}
hide();
Q_EMIT newMessage("Uploading image...");
@@ -384,6 +389,7 @@ void CaptureWidget::uploadScreenshot() {
void CaptureWidget::undo() {
if (!m_modifications.isEmpty()) {
m_modifications.pop_back();
m_screenshot->paintBaseModifications(m_modifications);
update();
}
}
@@ -464,7 +470,7 @@ void CaptureWidget::createCapture() {
close();
return;
}
m_screenshot = screen->grabWindow(0);
m_screenshot = new Screenshot(screen->grabWindow(0));
}
void CaptureWidget::initShortcuts() {
@@ -524,7 +530,7 @@ QPoint CaptureWidget::limitPointToRect(const QPoint &p, const QRect &r) const {
}
QRect CaptureWidget::getExtendedSelection() const {
auto devicePixelRatio = m_screenshot.devicePixelRatio();
auto devicePixelRatio = m_screenshot->getScreenshot().devicePixelRatio();
return QRect(m_selection.left() * devicePixelRatio,
m_selection.top() * devicePixelRatio,

View File

@@ -36,6 +36,7 @@ class CaptureModification;
class QNetworkAccessManager;
class QNetworkReply;
class ColorPicker;
class Screenshot;
class CaptureWidget : public QWidget {
Q_OBJECT
@@ -74,7 +75,7 @@ protected:
QRegion handleMask() const;
// pixel map of the screen
QPixmap m_screenshot;
Screenshot* m_screenshot;
QPoint m_dragStartPoint;
QPoint m_mousePos;

View File

@@ -21,6 +21,7 @@
#include <QStandardPaths>
#include <QIcon>
#include <QSettings>
#include <QDateTime>
#include <QObject>
#include <QString>
#include <QMessageBox>
@@ -34,22 +35,30 @@
// Screenshot is an extension of QPixmap which lets you manage specific tasks
Screenshot::Screenshot(const QPixmap &p) : m_screenshot(p) {
}
Screenshot::Screenshot(const QPixmap &p) : m_baseScreenshot(p),
m_modifiedScreenshot(p) {}
Screenshot::~Screenshot() {
if (m_accessManager) delete(m_accessManager);
}
void Screenshot::setScreenshot(const QPixmap &p) {
m_screenshot = p;
m_baseScreenshot = p;
m_modifiedScreenshot = p;
}
// getScreenshot returns the screenshot with no modifications
QPixmap Screenshot::getBaseScreenshot() const {
return m_baseScreenshot;
}
// getScreenshot returns the screenshot with all the modifications
QPixmap Screenshot::getScreenshot() const {
return m_screenshot;
return m_modifiedScreenshot;
}
// graphicalSave generates a graphical window to ask about the save path and
// saves the screenshot with all the modifications in such directory
QString Screenshot::graphicalSave(const QRect &selection) const {
const QString format = "png";
@@ -98,9 +107,9 @@ QString Screenshot::graphicalSave(const QRect &selection) const {
QPixmap pixToSave;
if (selection.isEmpty()) {
pixToSave = m_screenshot;
pixToSave = m_modifiedScreenshot;
} else { // save full screen when no selection
pixToSave = m_screenshot.copy(selection);
pixToSave = m_modifiedScreenshot.copy(selection);
}
// if (settings.value("mouseVisible").toBool()) {
@@ -115,52 +124,101 @@ QString Screenshot::graphicalSave(const QRect &selection) const {
return fileName;
}
QPixmap Screenshot::paintModifications(const QVector<CaptureModification> v) {
QPainter painter(&m_screenshot);
// paintModification adds a new modification to the screenshot
QPixmap Screenshot::paintModification(const CaptureModification &modification) {
QPainter painter(&m_modifiedScreenshot);
painter.setRenderHint(QPainter::Antialiasing);
for (CaptureModification modification: v) {
painter.setPen(QPen(modification.getColor(), 2));
QVector<QPoint> points = modification.getPoints();
switch (modification.getType()) {
case Button::Type::arrow:
painter.drawLine(points[0], points[1]);
// TODO
break;
case Button::Type::circle:
painter.drawEllipse(QRect(points[0], points[1]));
break;
case Button::Type::line:
painter.drawLine(points[0], points[1]);
break;
case Button::Type::marker:
painter.setOpacity(0.35);
painter.setPen(QPen(modification.getColor(), 14));
painter.drawLine(points[0], points[1]);
painter.setOpacity(1);
break;
case Button::Type::pencil:
painter.drawPolyline(points.data(), points.size());
break;
case Button::Type::rectangle:
painter.drawRect(QRect(points[0], points[1]));
break;
default:
break;
}
painter.setPen(QPen(modification.getColor(), 2));
QVector<QPoint> points = modification.getPoints();
switch (modification.getType()) {
case Button::Type::arrow:
painter.drawLine(points[0], points[1]);
// TODO
break;
case Button::Type::circle:
painter.drawEllipse(QRect(points[0], points[1]));
break;
case Button::Type::line:
painter.drawLine(points[0], points[1]);
break;
case Button::Type::marker:
painter.setOpacity(0.35);
painter.setPen(QPen(modification.getColor(), 14));
painter.drawLine(points[0], points[1]);
painter.setOpacity(1);
break;
case Button::Type::pencil:
painter.drawPolyline(points.data(), points.size());
break;
case Button::Type::rectangle:
painter.drawRect(QRect(points[0], points[1]));
break;
default:
break;
}
return m_screenshot;
return m_modifiedScreenshot;
}
QPixmap Screenshot::paintTemporalModification(const CaptureModification &modification) {
QPixmap tempPix = m_modifiedScreenshot;
QPainter painter(&tempPix);
if (modification.getType() != Button::Type::pencil) {
painter.setRenderHint(QPainter::Antialiasing);
}
painter.setPen(QPen(modification.getColor(), 2));
QVector<QPoint> points = modification.getPoints();
switch (modification.getType()) {
case Button::Type::arrow:
painter.drawLine(points[0], points[1]);
// TODO
break;
case Button::Type::circle:
painter.drawEllipse(QRect(points[0], points[1]));
break;
case Button::Type::line:
painter.drawLine(points[0], points[1]);
break;
case Button::Type::marker:
painter.setOpacity(0.35);
painter.setPen(QPen(modification.getColor(), 14));
painter.drawLine(points[0], points[1]);
painter.setOpacity(1);
break;
case Button::Type::pencil:
painter.drawPolyline(points.data(), points.size());
break;
case Button::Type::rectangle:
painter.drawRect(QRect(points[0], points[1]));
break;
default:
break;
}
return tempPix;
}
// paintBaseModifications overrides the modifications of the screenshot with new ones
QPixmap Screenshot::paintBaseModifications(const QVector<CaptureModification> &m) {
m_modifiedScreenshot = m_baseScreenshot;
for (const CaptureModification modification: m) {
paintModification(modification);
}
return m_modifiedScreenshot;
}
void Screenshot::uploadToImgur(QNetworkAccessManager *accessManager,
const QRect &selection) {
QString title ="asdasdf";
QString description = "test";
QString title ="flameshot_screenshot";
QString datetime = QDateTime().toString();
QString description = "flameshot " + datetime;
QPixmap pixToSave;
if (selection.isEmpty()) {
pixToSave = m_screenshot;
pixToSave = m_modifiedScreenshot;
} else { // save full screen when no selection
pixToSave = m_screenshot.copy(selection);
pixToSave = m_modifiedScreenshot.copy(selection);
}
QByteArray byteArray;
QBuffer buffer(&byteArray);

View File

@@ -32,14 +32,19 @@ public:
~Screenshot();
void setScreenshot(const QPixmap &);
QPixmap getBaseScreenshot() const;
QPixmap getScreenshot() const;
QString graphicalSave(const QRect &selection = QRect()) const;
void uploadToImgur(QNetworkAccessManager *,
const QRect &selection = QRect());
QPixmap paintModifications(const QVector<CaptureModification>);
QPixmap paintModification(const CaptureModification &);
QPixmap paintTemporalModification(const CaptureModification &);
QPixmap paintBaseModifications(const QVector<CaptureModification> &);
private:
QPixmap m_screenshot;
QPixmap m_baseScreenshot;
QPixmap m_modifiedScreenshot;
QPointer<QNetworkAccessManager> m_accessManager;
};

View File

@@ -47,11 +47,11 @@ void UIcolorEditor::initColorWheel() {
}
void UIcolorEditor::initButton() {
bool iconsAreWhite = false;
QString bgColor = this->palette().color(QWidget::backgroundRole()).name();
if (bgColor < QColor(Qt::gray).name()) {
iconsAreWhite = true;
}
bool iconsAreWhite = QSettings().value("whiteIconColor").toBool();
// QString bgColor = this->palette().color(QWidget::backgroundRole()).name();
// if (bgColor < QColor(Qt::gray).name()) {
// iconsAreWhite = true;
// }
m_button = new Button(Button::Type::circle, iconsAreWhite, this);
m_button->setStyleSheet(Button::getStyle());
}