QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
qgsrenderchecker.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsrenderchecker.h - check maprender output against an expected image
3 --------------------------------------
4 Date : 18 Jan 2008
5 Copyright : (C) 2008 by Tim Sutton
6 email : tim @ linfiniti.com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#ifndef QGSRENDERCHECKER_H
17#define QGSRENDERCHECKER_H
18
19#include "qgis_core.h"
20#include "qgis_sip.h"
21#include "qgsdartmeasurement.h"
22#include "qgslogger.h"
23#include "qgsmapsettings.h"
24
25#include <QDir>
26#include <QList>
27#include <QRegularExpression>
28#include <QString>
29
30class QImage;
31
32#define DUMP_BASE64_IMAGES 0
33
40class CORE_EXPORT QgsRenderChecker
41{
42 Q_GADGET
43
44 public:
45
50
56 static QDir testReportDir();
57
64 static bool shouldGenerateReport();
65
73 QString controlImagePath() const;
74
81 void setControlImagePath( const QString &path );
82
91 QString report( bool ignoreSuccess = true ) const;
92
102 QString markdownReport( bool ignoreSuccess = true ) const;
103
107 float matchPercent() const
108 {
109 return static_cast<float>( mMismatchCount ) /
110 static_cast<float>( mMatchTarget ) * 100;
111 }
112
116 unsigned int mismatchCount() const { return mMismatchCount; }
117
121 unsigned int matchTarget() const { return mMatchTarget; }
122
128 int elapsedTime() const { return mElapsedTime; }
129 void setElapsedTimeTarget( int target ) { mElapsedTimeTarget = target; }
130
138 void setControlName( const QString &name );
139
144 void setControlExtension( const QString &extension ) { mControlExtension = extension; }
145
150 void setControlPathPrefix( const QString &name ) { mControlPathPrefix = name + '/'; }
151
152 void setControlPathSuffix( const QString &name );
153
155 QString imageToHash( const QString &imageFile );
156
160 void setRenderedImage( const QString &imageFileName ) { mRenderedImageFile = imageFileName; }
161
167 void setExpectFail( bool expectFail ) { mExpectFail = expectFail; }
168
174 QString renderedImage() const { return mRenderedImageFile; }
175
176 void setMapSettings( const QgsMapSettings &mapSettings );
177
184 void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; }
185
191 void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; }
192
198 enum class Flag : int SIP_ENUM_BASETYPE( IntFlag )
199 {
200 AvoidExportingRenderedImage = 1 << 0,
201 Silent = 1 << 1,
202 };
203 Q_ENUM( Flag )
204
205
210 Q_DECLARE_FLAGS( Flags, Flag )
211 Q_FLAG( Flags )
212
225 bool runTest( const QString &testName, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
226
240 bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString(), QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
241
247 bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0, QgsRenderChecker::Flags flags = QgsRenderChecker::Flags() );
248
259 Q_DECL_DEPRECATED bool isKnownAnomaly( const QString &diffImageFile ) SIP_DEPRECATED;
260
265 static void drawBackground( QImage *image );
266
272 QString expectedImageFile() const { return mExpectedImageFile; }
273
281 void enableDashBuffering( bool enable ) { mBufferDashMessages = enable; }
282
289 QVector<QgsDartMeasurement> dartMeasurements() const { return mDashMessages; }
290
296 static QString sourcePath();
297
298 protected:
300 QString mReport;
303 unsigned int mMatchTarget = 0;
308
309 private:
310 void emitDashMessage( const QgsDartMeasurement &dashMessage );
311 void emitDashMessage( const QString &name, QgsDartMeasurement::Type type, const QString &value );
312
313#if DUMP_BASE64_IMAGES
314 void dumpRenderedImageAsBase64();
315#endif
316
317 void performPostTestActions( Flags flags );
318
319 bool mResult = false;
320 bool mExpectFail = false;
321
322 QString mBasePath;
323
324 QString mControlName;
325 unsigned int mMismatchCount = 0;
326 unsigned int mColorTolerance = 0;
327 int mMaxSizeDifferenceX = 0;
328 int mMaxSizeDifferenceY = 0;
329 int mElapsedTimeTarget = 0;
330 QgsMapSettings mMapSettings;
331 QString mControlExtension = QStringLiteral( "png" );
332 QString mControlPathPrefix;
333 QString mControlPathSuffix;
334 bool mIsCiRun = false;
335 QVector<QgsDartMeasurement> mDashMessages;
336 bool mBufferDashMessages = false;
337 QString mDiffImageFile;
338
340};
341
343
344
351
352inline bool compareWkt( const QString &a, const QString &b, double tolerance = 0.000001 )
353{
354 QgsDebugMsgLevel( QStringLiteral( "a:%1 b:%2 tol:%3" ).arg( a, b ).arg( tolerance ), 2 );
355 const thread_local QRegularExpression re( "-?\\d+(?:\\.\\d+)?(?:[eE]\\d+)?" );
356
357 QString a0( a ), b0( b );
358 a0.replace( re, QStringLiteral( "#" ) );
359 b0.replace( re, QStringLiteral( "#" ) );
360
361 QgsDebugMsgLevel( QStringLiteral( "a0:%1 b0:%2" ).arg( a0, b0 ), 2 );
362
363 if ( a0 != b0 )
364 return false;
365
366 QList<double> al, bl;
367
368 int pos = 0;
369 QRegularExpressionMatch match = re.match( a );
370 while ( match.hasMatch() )
371 {
372 al << match.captured( 0 ).toDouble();
373 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
374 match = re.match( a, pos );
375 }
376 match = re.match( b );
377 while ( match.hasMatch() )
378 {
379 bl << match.captured( 0 ).toDouble();
380 pos = match.capturedStart( 0 ) + match.capturedLength( 0 );
381 match = re.match( b, pos );
382 }
383
384 if ( al.size() != bl.size() )
385 return false;
386
387 for ( int i = 0; i < al.size(); i++ )
388 {
389 if ( !qgsDoubleNear( al[i], bl[i], tolerance ) )
390 return false;
391 }
392
393 return true;
394}
395
396#endif
Emits dart measurements for display in CDash reports.
Contains configuration for rendering maps.
Q_DECL_DEPRECATED bool isKnownAnomaly(const QString &diffImageFile)
Gets a list of all the anomalies.
static QDir testReportDir()
Returns the directory to use for generating a test report.
QString markdownReport(bool ignoreSuccess=true) const
Returns the markdown report describing the results of the test run.
void setControlExtension(const QString &extension)
Sets file extension for the control image.
friend class QgsMultiRenderChecker
float matchPercent() const
Returns the percent of pixels which matched the control image.
unsigned int matchTarget() const
Returns the total number of pixels in the control image.
QString mReport
HTML format report.
static bool shouldGenerateReport()
Returns true if a test report should be generated given the current environment.
unsigned int mMatchTarget
void setControlImagePath(const QString &path)
Sets the base path containing the reference images.
bool runTest(const QString &testName, unsigned int mismatchCount=0, QgsRenderChecker::Flags flags=QgsRenderChecker::Flags())
Test using renderer to generate the image to be compared.
QFlags< Flag > Flags
Render checker flags.
Flag
Render checker flags.
int elapsedTime() const
Returns the total elapsed time for the rendering test.
QString mMarkdownReport
Markdown report.
QString renderedImage() const
Returns the path of the rendered image generated by the test.
void setElapsedTimeTarget(int target)
QVector< QgsDartMeasurement > dartMeasurements() const
Gets access to buffered dash messages.
void setControlPathPrefix(const QString &name)
Sets the path prefix where the control images are kept.
QString report(bool ignoreSuccess=true) const
Returns the HTML report describing the results of the test run.
static void drawBackground(QImage *image)
Draws a checkboard pattern for image backgrounds, so that opacity is visible without requiring a tran...
bool compareImages(const QString &testName, unsigned int mismatchCount=0, const QString &renderedImageFile=QString(), QgsRenderChecker::Flags flags=QgsRenderChecker::Flags())
Test using two arbitrary images (map renderer will not be used).
void setRenderedImage(const QString &imageFileName)
Sets the file name of the rendered image generated by the test.
QgsRenderChecker()
Constructor for QgsRenderChecker.
QString controlImagePath() const
Returns the base path containing the reference images.
void setSizeTolerance(int xTolerance, int yTolerance)
Sets the largest allowable difference in size between the rendered and the expected image.
void enableDashBuffering(bool enable)
Call this to enable internal buffering of dash messages.
unsigned int mismatchCount() const
Returns the number of pixels which did not match the control image.
void setExpectFail(bool expectFail)
Sets whether the comparison is expected to fail.
void setColorTolerance(unsigned int colorTolerance)
Set tolerance for color components used by runTest() and compareImages().
QString expectedImageFile() const
Returns the path to the expected image file.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6607
#define SIP_DEPRECATED
Definition qgis_sip.h:114
#define SIP_ENUM_BASETYPE(type)
Definition qgis_sip.h:275
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
Q_DECLARE_OPERATORS_FOR_FLAGS(QgsProjectionSelectionWidget::CrsOptions)
bool compareWkt(const QString &a, const QString &b, double tolerance=0.000001)
Compare two WKT strings with some tolerance.