forked from qt-creator/qt-creator
QtSupport: Resurrect the "screenshot cropper" tool
After many Years, it is time to refresh "images_areaofinterest.xml". That is best done with the "screenshot cropper" tool. Change-Id: Icd07e1c1697e236855d3a03ae8977044d21d78f7 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
This commit is contained in:
@@ -58,9 +58,8 @@ static inline QString fileNameForPath(const QString &path)
|
||||
static QRect cropRectForAreaOfInterest(const QSize &imageSize, const QSize &cropSize, const QRect &areaOfInterest)
|
||||
{
|
||||
QRect result;
|
||||
const qreal cropSizeToAreaSizeFactor = qMin(cropSize.width() / qreal(areaOfInterest.width()),
|
||||
cropSize.height() / qreal(areaOfInterest.height()));
|
||||
if (cropSizeToAreaSizeFactor >= 1) {
|
||||
if (areaOfInterest.width() <= cropSize.width()
|
||||
&& areaOfInterest.height() <= cropSize.height()) {
|
||||
const QPoint areaOfInterestCenter = areaOfInterest.center();
|
||||
const int cropX = qBound(0,
|
||||
areaOfInterestCenter.x() - cropSize.width() / 2,
|
||||
@@ -72,19 +71,28 @@ static QRect cropRectForAreaOfInterest(const QSize &imageSize, const QSize &crop
|
||||
const int cropHeight = qMin(imageSize.height(), cropSize.height());
|
||||
result = QRect(cropX, cropY, cropWidth, cropHeight);
|
||||
} else {
|
||||
QSize resultSize = cropSize.expandedTo(areaOfInterest.size());
|
||||
QSize resultSize = cropSize.scaled(areaOfInterest.width(), areaOfInterest.height(),
|
||||
Qt::KeepAspectRatioByExpanding);
|
||||
result = QRect(QPoint(), resultSize);
|
||||
result.moveCenter(areaOfInterest.center());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QImage ScreenshotCropper::croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize)
|
||||
} // namespace Internal
|
||||
|
||||
namespace ScreenshotCropper {
|
||||
|
||||
QImage croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize,
|
||||
const QRect &areaOfInterest)
|
||||
{
|
||||
const QRect areaOfInterest = welcomeScreenAreas()->areas.value(fileNameForPath(filePath));
|
||||
const QRect area = areaOfInterest.isValid() ? areaOfInterest :
|
||||
Internal::welcomeScreenAreas()->areas.value(Internal::fileNameForPath(filePath));
|
||||
|
||||
QImage result;
|
||||
if (areaOfInterest.isValid()) {
|
||||
const QRect cropRect = cropRectForAreaOfInterest(sourceImage.size(), cropSize, areaOfInterest);
|
||||
if (area.isValid()) {
|
||||
const QRect cropRect = Internal::cropRectForAreaOfInterest(sourceImage.size(),
|
||||
cropSize, areaOfInterest);
|
||||
const QSize cropRectSize = cropRect.size();
|
||||
result = sourceImage.copy(cropRect);
|
||||
if (cropRectSize.width() <= cropSize.width() && cropRectSize.height() <= cropSize.height())
|
||||
@@ -115,7 +123,7 @@ static const QString xmlAttributeY = QLatin1String("y");
|
||||
static const QString xmlAttributeWidth = QLatin1String("width");
|
||||
static const QString xmlAttributeHeight = QLatin1String("height");
|
||||
|
||||
QMap<QString, QRect> ScreenshotCropper::loadAreasOfInterest(const QString &areasXmlFile)
|
||||
QMap<QString, QRect> loadAreasOfInterest(const QString &areasXmlFile)
|
||||
{
|
||||
QMap<QString, QRect> areasOfInterest;
|
||||
QFile xmlFile(areasXmlFile);
|
||||
@@ -146,7 +154,7 @@ QMap<QString, QRect> ScreenshotCropper::loadAreasOfInterest(const QString &areas
|
||||
return areasOfInterest;
|
||||
}
|
||||
|
||||
bool ScreenshotCropper::saveAreasOfInterest(const QString &areasXmlFile, QMap<QString, QRect> &areas)
|
||||
bool saveAreasOfInterest(const QString &areasXmlFile, QMap<QString, QRect> &areas)
|
||||
{
|
||||
QFile file(areasXmlFile);
|
||||
if (!file.open(QIODevice::WriteOnly))
|
||||
@@ -169,5 +177,5 @@ bool ScreenshotCropper::saveAreasOfInterest(const QString &areasXmlFile, QMap<QS
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // ScreenshotCropper
|
||||
} // namespace QtSupport
|
||||
|
@@ -25,20 +25,24 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qtsupport_global.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QRect>
|
||||
#include <QImage>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QImage;
|
||||
class QSize;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QtSupport {
|
||||
namespace Internal {
|
||||
namespace ScreenshotCropper {
|
||||
|
||||
class ScreenshotCropper
|
||||
{
|
||||
public:
|
||||
static QImage croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize);
|
||||
static QMap<QString, QRect> loadAreasOfInterest(const QString &areasXmlFile);
|
||||
static bool saveAreasOfInterest(const QString &areasXmlFile, QMap<QString, QRect> &areas);
|
||||
};
|
||||
QTSUPPORT_EXPORT QImage croppedImage(const QImage &sourceImage, const QString &filePath,
|
||||
const QSize &cropSize, const QRect &areaOfInterest = {});
|
||||
QTSUPPORT_EXPORT QMap<QString, QRect> loadAreasOfInterest(const QString &areasXmlFile);
|
||||
QTSUPPORT_EXPORT bool saveAreasOfInterest(const QString &areasXmlFile,
|
||||
QMap<QString, QRect> &areas);
|
||||
|
||||
} // namespace Internal
|
||||
} // ScreenshotCropper
|
||||
} // namespace QtSupport
|
||||
|
@@ -42,7 +42,7 @@ add_subdirectory(qtc-askpass)
|
||||
add_subdirectory(qtcreatorcrashhandler)
|
||||
# add_subdirectory(qtcreatorwidgets) ## qbs does not build this either
|
||||
add_subdirectory(qtpromaker)
|
||||
# add_subdirectory(screenshotcropper) ## qbs does not build this either
|
||||
add_subdirectory(screenshotcropper)
|
||||
add_subdirectory(sdktool)
|
||||
add_subdirectory(valgrindfake)
|
||||
add_subdirectory(wininterrupt) ## windows only
|
||||
|
@@ -1,22 +1,9 @@
|
||||
#
|
||||
# Copyright (C) YourCompany. All rights reserved.
|
||||
#
|
||||
# GENERATED BY CPP-DEPENDENCIES - do not edit, your changes will be lost
|
||||
# If you must edit, remove these two lines to avoid regeneration
|
||||
|
||||
project(src.tools.screenshotcropper)
|
||||
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC
|
||||
cropimageview.cpp
|
||||
cropimageview.h
|
||||
main.cpp
|
||||
screenshotcropperwindow.cpp
|
||||
screenshotcropperwindow.h
|
||||
add_qtc_executable(screenshotcropper
|
||||
SKIP_INSTALL
|
||||
DEPENDS Qt5::Widgets Utils Core QtSupport
|
||||
SOURCES
|
||||
main.cpp
|
||||
cropimageview.cpp
|
||||
cropimageview.h
|
||||
screenshotcropperwindow.h screenshotcropperwindow.cpp screenshotcropperwindow.ui
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
src.plugins.qtsupport
|
||||
)
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "cropimageview.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
|
||||
@@ -34,19 +35,18 @@ CropImageView::CropImageView(QWidget *parent)
|
||||
|
||||
void CropImageView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
setArea(QRect(event->pos(), m_area.bottomRight()));
|
||||
update();
|
||||
m_initialPoint = event->pos();
|
||||
setEndPoint(m_initialPoint);
|
||||
}
|
||||
|
||||
void CropImageView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
setArea(QRect(m_area.topLeft(), event->pos()));
|
||||
update();
|
||||
setEndPoint(event->pos());
|
||||
}
|
||||
|
||||
void CropImageView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
mouseMoveEvent(event);
|
||||
setEndPoint(event->pos());
|
||||
}
|
||||
|
||||
void CropImageView::setImage(const QImage &image)
|
||||
@@ -63,6 +63,11 @@ void CropImageView::setArea(const QRect &area)
|
||||
update();
|
||||
}
|
||||
|
||||
void CropImageView::setEndPoint(const QPoint &point)
|
||||
{
|
||||
setArea(QRect(m_initialPoint, point));
|
||||
}
|
||||
|
||||
void CropImageView::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
@@ -41,6 +41,7 @@ public:
|
||||
|
||||
void setImage(const QImage &image);
|
||||
void setArea(const QRect &area);
|
||||
void setEndPoint(const QPoint &point);
|
||||
|
||||
signals:
|
||||
void cropAreaChanged(const QRect &area);
|
||||
@@ -48,4 +49,5 @@ signals:
|
||||
private:
|
||||
QImage m_image;
|
||||
QRect m_area;
|
||||
QPoint m_initialPoint;
|
||||
};
|
||||
|
@@ -29,8 +29,6 @@
|
||||
|
||||
#include "screenshotcropperwindow.h"
|
||||
|
||||
using namespace QtSupport::Internal;
|
||||
|
||||
const QString settingsKeyAreasXmlFile = QLatin1String("areasXmlFile");
|
||||
const QString settingsKeyImagesFolder = QLatin1String("imagesFolder");
|
||||
|
||||
|
@@ -25,11 +25,13 @@
|
||||
|
||||
#include "screenshotcropperwindow.h"
|
||||
#include "ui_screenshotcropperwindow.h"
|
||||
|
||||
#include <coreplugin/welcomepagehelper.h>
|
||||
#include <qtsupport/screenshotcropper.h>
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QtSupport::Internal;
|
||||
|
||||
ScreenShotCropperWindow::ScreenShotCropperWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::ScreenShotCropperWindow)
|
||||
@@ -51,7 +53,7 @@ void ScreenShotCropperWindow::loadData(const QString &areasXmlFile, const QStrin
|
||||
typedef QMap<QString, QRect>::ConstIterator StringRectConstIt;
|
||||
|
||||
m_areasOfInterestFile = areasXmlFile;
|
||||
m_areasOfInterest = ScreenshotCropper::loadAreasOfInterest(m_areasOfInterestFile);
|
||||
m_areasOfInterest = QtSupport::ScreenshotCropper::loadAreasOfInterest(m_areasOfInterestFile);
|
||||
m_imagesFolder = imagesFolder;
|
||||
const StringRectConstIt cend = m_areasOfInterest.constEnd();
|
||||
for (StringRectConstIt it = m_areasOfInterest.constBegin(); it != cend; ++it)
|
||||
@@ -70,12 +72,25 @@ void ScreenShotCropperWindow::setArea(const QRect &area)
|
||||
const QListWidgetItem *item = ui->m_filenamesList->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (!area.isValid()) {
|
||||
ui->m_previewLabel->setPixmap({});
|
||||
return;
|
||||
}
|
||||
|
||||
const QString currentFile = item->text();
|
||||
m_areasOfInterest.insert(currentFile, area);
|
||||
const QImage img(m_imagesFolder + QLatin1Char('/') + currentFile);
|
||||
const QPixmap cropped = QPixmap::fromImage(
|
||||
QtSupport::ScreenshotCropper::croppedImage(img, currentFile,
|
||||
Core::ListModel::defaultImageSize,
|
||||
area));
|
||||
ui->m_previewLabel->setPixmap(cropped);
|
||||
}
|
||||
|
||||
void ScreenShotCropperWindow::saveData()
|
||||
{
|
||||
if (!ScreenshotCropper::saveAreasOfInterest(m_areasOfInterestFile, m_areasOfInterest))
|
||||
if (!QtSupport::ScreenshotCropper::saveAreasOfInterest(m_areasOfInterestFile,
|
||||
m_areasOfInterest))
|
||||
qFatal("Cannot write %s", qPrintable(m_areasOfInterestFile));
|
||||
}
|
||||
|
@@ -25,11 +25,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qtsupport/screenshotcropper.h>
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
using namespace QtSupport::Internal;
|
||||
#include <QMap>
|
||||
#include <QRect>
|
||||
|
||||
namespace Ui { class ScreenShotCropperWindow; }
|
||||
|
||||
|
@@ -15,6 +15,13 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="m_buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
@@ -43,29 +50,39 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>398</width>
|
||||
<height>435</height>
|
||||
<width>386</width>
|
||||
<height>438</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="margin" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="CropImageView" name="m_cropImageView" native="true"/>
|
||||
<widget class="CropImageView" name="m_cropImageView" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="m_buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Save</set>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="m_previewLabel">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
Reference in New Issue
Block a user