Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmultirenderchecker.h 3 : : -------------------------------------- 4 : : Date : 6.11.2014 5 : : Copyright : (C) 2014 Matthias Kuhn 6 : : Email : matthias at opengis dot ch 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 QGSMULTIRENDERCHECKER_H 17 : : #define QGSMULTIRENDERCHECKER_H 18 : : 19 : : #include "qgis_core.h" 20 : : #include "qgsrenderchecker.h" 21 : : 22 : : class QgsLayout; 23 : : 24 : : /** 25 : : * \ingroup core 26 : : * \brief This class allows checking rendered images against comparison images. 27 : : * 28 : : * Its main purpose is for the unit testing framework. 29 : : * 30 : : * It will either 31 : : * <ul> 32 : : * <li>take an externally rendered image (setRenderedImage())</li> 33 : : * <li>render the image based on provided mapSettings (setMapSettings())</li> 34 : : * </ul> 35 : : * 36 : : * This image will then be compared against one or several images in a folder inside 37 : : * the control directory (tests/testdata/control_images/{controlName}). 38 : : * 39 : : * There are modes for single and for multiple reference images. 40 : : * <ul> 41 : : * <li>If there are no subfolders in the control directory, it will assume an image 42 : : * with the name {controlImage}.png in the control directory itself.</li> 43 : : * 44 : : * <li>If there are subfolders inside the control directory, it will search for images 45 : : * with the name {controlImage}.png in every subfolder.</li> 46 : : * </ul> 47 : : * 48 : : * For every control image there may be one or several randomly named anomaly images defining 49 : : * allowed anomalies. 50 : : * For every control image, the allowed mismatch and color tolerance values will be calculated 51 : : * individually. 52 : : * 53 : : * \since QGIS 2.8 54 : : */ 55 : : 56 : : class CORE_EXPORT QgsMultiRenderChecker 57 : : { 58 : : public: 59 : : 60 : : /** 61 : : * Constructor for QgsMultiRenderChecker. 62 : : */ 63 : 0 : QgsMultiRenderChecker() = default; 64 : : 65 : 0 : virtual ~QgsMultiRenderChecker() = default; 66 : : 67 : : /** 68 : : * Base directory name for the control image (with control image path 69 : : * suffixed) the path to the image will be constructed like this: 70 : : * controlImagePath + '/' + mControlName + '/' + mControlName + '.png' 71 : : */ 72 : : void setControlName( const QString &name ); 73 : : 74 : : void setControlPathPrefix( const QString &prefix ); 75 : : 76 : : /** 77 : : * Set the path to the rendered image. If this is not set or set to null QString, an image 78 : : * will be rendered based on the provided mapsettings 79 : : * 80 : : * \param renderedImagePath A path to the rendered image with which control images will be compared 81 : : */ 82 : 0 : void setRenderedImage( const QString &renderedImagePath ) { mRenderedImage = renderedImagePath; } 83 : : 84 : : /** 85 : : * Set the map settings to use to render the image 86 : : * 87 : : * \param mapSettings The map settings 88 : : */ 89 : : void setMapSettings( const QgsMapSettings &mapSettings ); 90 : : 91 : : /** 92 : : * Set tolerance for color components used by runTest() 93 : : * Default value is 0. 94 : : * 95 : : * \param colorTolerance The maximum difference for each color component 96 : : * including alpha to be considered correct. 97 : : */ 98 : 0 : void setColorTolerance( unsigned int colorTolerance ) { mColorTolerance = colorTolerance; } 99 : : 100 : : /** 101 : : * Sets the largest allowable difference in size between the rendered and the expected image. 102 : : * \param xTolerance x tolerance in pixels 103 : : * \param yTolerance y tolerance in pixels 104 : : * \since QGIS 3.0 105 : : */ 106 : : void setSizeTolerance( int xTolerance, int yTolerance ) { mMaxSizeDifferenceX = xTolerance; mMaxSizeDifferenceY = yTolerance; } 107 : : 108 : : /** 109 : : * Test using renderer to generate the image to be compared. 110 : : * 111 : : * \param testName - to be used as the basis for writing a file to 112 : : * e.g. /tmp/theTestName.png 113 : : * 114 : : * \param mismatchCount - defaults to 0 - the number of pixels that 115 : : * are allowed to be different from the control image. In some cases 116 : : * rendering may be non-deterministic. This parameter allows you to account 117 : : * for that by providing a tolerance. 118 : : * 119 : : * \note make sure to call setExpectedImage and setMapSettings first 120 : : */ 121 : : bool runTest( const QString &testName, unsigned int mismatchCount = 0 ); 122 : : 123 : : /** 124 : : * Returns a report for this test 125 : : */ 126 : 0 : QString report() const { return mReport; } 127 : : 128 : : /** 129 : : * Returns the path to the control images. 130 : : */ 131 : : QString controlImagePath() const; 132 : : 133 : : /** 134 : : * Draws a checkboard pattern for image backgrounds, so that opacity is visible 135 : : * without requiring a transparent background for the image 136 : : */ 137 : 0 : static void drawBackground( QImage *image ) { QgsRenderChecker::drawBackground( image ); } 138 : : 139 : : private: 140 : : QString mReport; 141 : : QString mRenderedImage; 142 : : QString mControlName; 143 : : QString mControlPathPrefix; 144 : 0 : unsigned int mColorTolerance = 0; 145 : 0 : int mMaxSizeDifferenceX = 0; 146 : 0 : int mMaxSizeDifferenceY = 0; 147 : : QgsMapSettings mMapSettings; 148 : : }; 149 : : 150 : : SIP_FEATURE( TESTS ) 151 : : SIP_IF_FEATURE( TESTS ) 152 : : 153 : : ///@cond PRIVATE 154 : : 155 : : /** 156 : : * \ingroup core 157 : : * \class QgsLayoutChecker 158 : : * \brief Renders a layout to an image and compares with an expected output 159 : : * \since QGIS 3.0 160 : : */ 161 : 0 : class CORE_EXPORT QgsLayoutChecker : public QgsMultiRenderChecker 162 : : { 163 : : public: 164 : : 165 : : /** 166 : : * Constructor for QgsLayoutChecker. 167 : : */ 168 : : QgsLayoutChecker( const QString &testName, QgsLayout *layout ); 169 : : 170 : : /** 171 : : * Sets the output (reference) image \a size. 172 : : */ 173 : : void setSize( QSize size ) { mSize = size; } 174 : : 175 : : /** 176 : : * Runs a render check on the layout, adding results to the specified \a report. 177 : : * 178 : : * The maximum number of allowable pixels differing from the reference image is 179 : : * specified via the \a pixelDiff argument. 180 : : * 181 : : * A reference image can be created by setting \a createReferenceImage to TRUE 182 : : * in this case the test will always return TRUE. 183 : : * 184 : : * The page number is specified via \a page, where 0 corresponds to the first 185 : : * page in the layout. 186 : : * 187 : : * Returns FALSE if the rendered layout differs from the expected reference image. 188 : : */ 189 : : bool testLayout( QString &report, int page = 0, int pixelDiff = 0, bool createReferenceImage = false ); 190 : : 191 : : private: 192 : : QgsLayoutChecker() = delete; 193 : : 194 : : QString mTestName; 195 : : QgsLayout *mLayout = nullptr; 196 : : QSize mSize; 197 : : int mDotsPerMeter; 198 : : }; 199 : : ///@endcond 200 : : 201 : : SIP_END 202 : : 203 : : 204 : : #endif // QGSMULTIRENDERCHECKER_H