Skip to content
Permalink
Browse files

Use QgsRenderChecker to compare png images when comparing processing …

…result

directories
  • Loading branch information
nyalldawson committed Feb 8, 2021
1 parent 1af0834 commit 973682baa39fff36540703651b71d2ca40cb8df6
@@ -165,6 +165,13 @@ Test using two arbitrary images (map renderer will not be used)
for that by providing a tolerance.
:param renderedImageFile: to optionally override the output filename
\note: make sure to call setExpectedImage and setRenderedImage first.
%End

bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0 );
%Docstring
Test using two arbitrary images at the specified paths for equality.

.. versionadded:: 3.18
%End

bool isKnownAnomaly( const QString &diffImageFile );
@@ -35,7 +35,8 @@
QgsFeatureRequest,
QgsCoordinateReferenceSystem,
NULL,
QgsVectorLayer
QgsVectorLayer,
QgsRenderChecker
)

import unittest
@@ -226,21 +227,28 @@ def assertDirectoryEqual(self, dirpath_expected: str, dirpath_result: str):

contents_result = list(path_result.iterdir())
contents_expected = list(path_expected.iterdir())
contents_expected = [p for p in contents_expected if p.suffix != '.png' or not p.stem.endswith('_mask')]
self.assertCountEqual([p.name if p.is_file() else p.stem for p in contents_expected], [p.name if p.is_file() else p.stem for p in contents_result], f'Directory contents mismatch in {dirpath_expected} vs {dirpath_result}')

# compare file contents
for expected_file_path in path_expected.iterdir():
for expected_file_path in contents_expected:
if expected_file_path.is_dir():
continue

result_file_path = path_result / expected_file_path.name

if expected_file_path.suffix == '.pbf':
# vector layer, use assertLayersEqual
layer_expected = QgsVectorLayer(str(expected_file_path), 'Expected')
self.assertTrue(layer_expected.isValid())
layer_result = QgsVectorLayer(str(result_file_path), 'Result')
self.assertTrue(layer_result.isValid())
self.assertLayersEqual(layer_expected, layer_result)
elif expected_file_path.suffix == '.png':
# image file, use QgsRenderChecker
checker = QgsRenderChecker()
res = checker.compareImages(expected_file_path.stem, expected_file_path.as_posix(), result_file_path.as_posix())
self.assertTrue(res)
else:
assert False, f"Don't know how to compare {expected_file_path.suffix} files"

@@ -251,6 +251,12 @@ bool QgsRenderChecker::compareImages( const QString &testName,
"Image File not set.</td></tr></table>\n";
return false;
}

return compareImages( testName, mExpectedImageFile, renderedImageFile, mismatchCount );
}

bool QgsRenderChecker::compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount )
{
if ( ! renderedImageFile.isEmpty() )
{
mRenderedImageFile = renderedImageFile;
@@ -272,7 +278,7 @@ bool QgsRenderChecker::compareImages( const QString &testName,
//
// Load /create the images
//
QImage myExpectedImage( mExpectedImageFile );
QImage myExpectedImage( referenceImageFile );
QImage myResultImage( mRenderedImageFile );
if ( myResultImage.isNull() )
{
@@ -290,7 +296,7 @@ bool QgsRenderChecker::compareImages( const QString &testName,
myDifferenceImage.fill( qRgb( 152, 219, 249 ) );

//check for mask
QString maskImagePath = mExpectedImageFile;
QString maskImagePath = referenceImageFile;
maskImagePath.chop( 4 ); //remove .png extension
maskImagePath += QLatin1String( "_mask.png" );
const QImage maskImage( maskImagePath );
@@ -343,7 +349,7 @@ bool QgsRenderChecker::compareImages( const QString &testName,
.arg( testName,
myDiffImageFile,
mRenderedImageFile,
mExpectedImageFile )
referenceImageFile )
.arg( imgWidth ).arg( imgHeight )
.arg( QUuid::createUuid().toString().mid( 1, 6 ) );

@@ -356,7 +362,7 @@ bool QgsRenderChecker::compareImages( const QString &testName,
// To get the images into CDash
//
emitDashMessage( "Rendered Image " + testName + prefix, QgsDartMeasurement::ImagePng, mRenderedImageFile );
emitDashMessage( "Expected Image " + testName + prefix, QgsDartMeasurement::ImagePng, mExpectedImageFile );
emitDashMessage( "Expected Image " + testName + prefix, QgsDartMeasurement::ImagePng, referenceImageFile );

//
// Put the same info to debug too
@@ -524,7 +530,7 @@ bool QgsRenderChecker::compareImages( const QString &testName,
"you can do something like this\n"
"cp '" + myDiffImageFile + "' " + controlImagePath() + mControlName +
"/\nIf it should be included in the mask run\n"
"scripts/generate_test_mask_image.py '" + mExpectedImageFile + "' '" + mRenderedImageFile + "'\n" );
"scripts/generate_test_mask_image.py '" + referenceImageFile + "' '" + mRenderedImageFile + "'\n" );

mReport += QLatin1String( "<tr><td colspan = 3>\n" );
mReport += "<font color=red>Test image and result image for " + testName + " are mismatched</font><br>";
@@ -170,6 +170,13 @@ class CORE_EXPORT QgsRenderChecker
*/
bool compareImages( const QString &testName, unsigned int mismatchCount = 0, const QString &renderedImageFile = QString() );

/**
* Test using two arbitrary images at the specified paths for equality.
*
* \since QGIS 3.18
*/
bool compareImages( const QString &testName, const QString &referenceImageFile, const QString &renderedImageFile, unsigned int mismatchCount = 0 );

/**
* Gets a list of all the anomalies. An anomaly is a rendered difference
* file where there is some red pixel content (indicating a render check

0 comments on commit 973682b

Please sign in to comment.