diff options
author | Alessandro Portale <alessandro.portale@nokia.com> | 2011-11-24 15:14:53 +0100 |
---|---|---|
committer | Alessandro Portale <alessandro.portale@nokia.com> | 2011-11-25 17:12:58 +0100 |
commit | 6c36a2a9ad5e495d31c2e20e7e76e57a0ede684f (patch) | |
tree | 99e1d8ce8543fa6982b37826f8dadb0ed1979cd9 /src/plugins/qtsupport/screenshotcropper.cpp | |
parent | 9e0cae5dac4d388caa948205a8e72cda199a213f (diff) | |
download | qt-creator-6c36a2a9ad5e495d31c2e20e7e76e57a0ede684f.tar.gz |
Cropping the examples screen shots to "Areas of interest".
The cropping coordinates are stored in a file
images_areasofinterest.xml. A tool to create/maintain the cropping
coordinates is included in this patch.
Then changes to Delegate.qml prevent QML from scaling the image.
If scaling is needed it is now the job of the Image provider.
dropshadow.png had to be adjusted because the border had different
widths and heights.
Change-Id: Ib25db896d40eeec0e0a373c971931dc5cabf3cbe
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Diffstat (limited to 'src/plugins/qtsupport/screenshotcropper.cpp')
-rw-r--r-- | src/plugins/qtsupport/screenshotcropper.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/plugins/qtsupport/screenshotcropper.cpp b/src/plugins/qtsupport/screenshotcropper.cpp new file mode 100644 index 0000000000..e678e40cf0 --- /dev/null +++ b/src/plugins/qtsupport/screenshotcropper.cpp @@ -0,0 +1,141 @@ +#include "screenshotcropper.h" + +#include <coreplugin/icore.h> +#include <QtCore/QXmlStreamReader> +#include <QtCore/QXmlStreamWriter> +#include <QtCore/QDebug> +#include <QtCore/QFile> +#include <QtCore/QFileInfo> +#include <QtGui/QPainter> + +namespace QtSupport { +namespace Internal { + +#ifdef QT_CREATOR +Q_GLOBAL_STATIC_WITH_INITIALIZER(AreasOfInterest, areasOfInterest, { + *x = ScreenshotCropper::loadAreasOfInterest(Core::ICore::instance()->resourcePath() + QLatin1String("/welcomescreen/images_areaofinterest.xml")); +}) +#else +Q_GLOBAL_STATIC(AreasOfInterest, areasOfInterest) +#endif // QT_CREATOR + +static inline QString fileNameForPath(const QString &path) +{ + return QFileInfo(path).fileName(); +} + +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) { + const QPoint areaOfInterestCenter = areaOfInterest.center(); + const int cropX = qBound(0, + areaOfInterestCenter.x() - cropSize.width() / 2, + imageSize.width() - cropSize.width()); + const int cropY = qBound(0, + areaOfInterestCenter.y() - cropSize.height() / 2, + imageSize.height() - cropSize.height()); + const int cropWidth = qMin(imageSize.width(), cropSize.width()); + const int cropHeight = qMin(imageSize.height(), cropSize.height()); + result = QRect(cropX, cropY, cropWidth, cropHeight); + } else { + QSize resultSize = cropSize.expandedTo(areaOfInterest.size()); + result = QRect(QPoint(), resultSize); + } + return result; +} + +QImage ScreenshotCropper::croppedImage(const QImage &sourceImage, const QString &filePath, const QSize &cropSize) +{ + const QRect areaOfInterest = areasOfInterest()->value(fileNameForPath(filePath)); + + if (areaOfInterest.isValid()) { + const QRect cropRect = cropRectForAreaOfInterest(sourceImage.size(), cropSize, areaOfInterest); + const QSize cropRectSize = cropRect.size(); + const QImage result = sourceImage.copy(cropRect); + if (cropRectSize.width() > cropSize.width() || cropRectSize.height() > cropSize.height()) + return result.scaled(cropSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + else + return result; + } + + return sourceImage.scaled(cropSize, Qt::KeepAspectRatio); +} + +static int areaAttribute(const QXmlStreamAttributes &attributes, const QString &name) +{ + bool ok; + const int result = attributes.value(name).toString().toInt(&ok); + if (!ok) + qWarning() << Q_FUNC_INFO << "Could not parse" << name << "for" << attributes.value(QLatin1String("image")).toString(); + return result; +} + +static const QString xmlTagAreas = QLatin1String("areas"); +static const QString xmlTagArea = QLatin1String("area"); +static const QString xmlAttributeImage = QLatin1String("image"); +static const QString xmlAttributeX = QLatin1String("x"); +static const QString xmlAttributeY = QLatin1String("y"); +static const QString xmlAttributeWidth = QLatin1String("width"); +static const QString xmlAttributeHeight = QLatin1String("height"); + +AreasOfInterest ScreenshotCropper::loadAreasOfInterest(const QString &areasXmlFile) +{ + AreasOfInterest areasOfInterest; + QFile xmlFile(areasXmlFile); + if (!xmlFile.open(QIODevice::ReadOnly)) { + qWarning() << Q_FUNC_INFO << "Could not open file" << areasXmlFile; + return areasOfInterest; + } + QXmlStreamReader reader(&xmlFile); + while (!reader.atEnd()) { + switch (reader.readNext()) { + case QXmlStreamReader::StartElement: + if (reader.name() == xmlTagArea) { + const QXmlStreamAttributes attributes = reader.attributes(); + const QString imageName = attributes.value(xmlAttributeImage).toString(); + if (imageName.isEmpty()) + qWarning() << Q_FUNC_INFO << "Could not parse name"; + + const QRect area(areaAttribute(attributes, xmlAttributeX), areaAttribute(attributes, xmlAttributeY), + areaAttribute(attributes, xmlAttributeWidth), areaAttribute(attributes, xmlAttributeHeight)); + areasOfInterest.insert(imageName, area); + } + break; + default: // nothing + break; + } + } + + return areasOfInterest; +} + +bool ScreenshotCropper::saveAreasOfInterest(const QString &areasXmlFile, AreasOfInterest &areas) +{ + QFile file(areasXmlFile); + if (!file.open(QIODevice::WriteOnly)) + return false; + QXmlStreamWriter writer(&file); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement(xmlTagAreas); + QMapIterator<QString, QRect> i(areas); + while (i.hasNext()) { + i.next(); + writer.writeStartElement(xmlTagArea); + writer.writeAttribute(xmlAttributeImage, i.key()); + writer.writeAttribute(xmlAttributeX, QString::number(i.value().x())); + writer.writeAttribute(xmlAttributeY, QString::number(i.value().y())); + writer.writeAttribute(xmlAttributeWidth, QString::number(i.value().width())); + writer.writeAttribute(xmlAttributeHeight, QString::number(i.value().height())); + writer.writeEndElement(); // xmlTagArea + } + writer.writeEndElement(); // xmlTagAreas + writer.writeEndDocument(); + return true; +} + +} // namespace Internal +} // namespace QtSupport |