Skip to content

Commit

Permalink
Merge pull request #9525 from rldhont/fix-server-getprint-jpg
Browse files Browse the repository at this point in the history
[Server] JPEG output for WMS GetPrint request has gone
  • Loading branch information
rldhont committed Mar 20, 2019
2 parents 5653289 + 547fd68 commit 638650a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 34 deletions.
32 changes: 17 additions & 15 deletions src/server/services/wms/qgswmsgetprint.cpp
Expand Up @@ -35,22 +35,24 @@ namespace QgsWms
QString contentType;

// GetPrint supports svg/png/pdf
if ( format == QgsWmsParameters::PNG )
switch ( format )
{
contentType = "image/png";
}
else if ( format == QgsWmsParameters::SVG )
{
contentType = "image/svg+xml";
}
else if ( format == QgsWmsParameters::PDF )
{
contentType = "application/pdf";
}
else
{
throw QgsServiceException( QStringLiteral( "InvalidFormat" ),
QString( "Output format %1 is not supported by the GetPrint request" ).arg( wmsParameters.formatAsString() ) );
case QgsWmsParameters::PNG:
contentType = QStringLiteral( "image/png" );
break;
case QgsWmsParameters::JPG:
contentType = QStringLiteral( "image/jpeg" );
break;
case QgsWmsParameters::SVG:
contentType = QStringLiteral( "image/svg+xml" );
break;
case QgsWmsParameters::PDF:
contentType = QStringLiteral( "application/pdf" );
break;
default:
throw QgsServiceException( QStringLiteral( "InvalidFormat" ),
QString( "Output format %1 is not supported by the GetPrint request" ).arg( wmsParameters.formatAsString() ) );
break;
}

response.setHeader( QStringLiteral( "Content-Type" ), contentType );
Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wms/qgswmsrenderer.cpp
Expand Up @@ -514,7 +514,7 @@ namespace QgsWms
exporter.exportToSvg( tempOutputFile.fileName(), exportSettings );
}
}
else if ( format == QgsWmsParameters::PNG )
else if ( format == QgsWmsParameters::PNG || format == QgsWmsParameters::JPG )
{
// Settings for the layout exporter
QgsLayoutExporter::ImageExportSettings exportSettings;
Expand Down
46 changes: 30 additions & 16 deletions tests/src/python/test_qgsserver.py
Expand Up @@ -176,12 +176,20 @@ def _result(self, data):

return data[1], headers

def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
temp_image = os.path.join(tempfile.gettempdir(), "%s_result.png" % control_image)
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputJpg=False):

extFile = 'png'
if outputJpg:
extFile = 'jpg'

temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile))

with open(temp_image, "wb") as f:
f.write(image)

if outputJpg:
return (True, "QgsRenderChecker can't be used for JPG images")

control = QgsRenderChecker()
control.setControlPathPrefix("qgis_server")
control.setControlName(control_image)
Expand All @@ -190,35 +198,41 @@ def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
control.setSizeTolerance(max_size_diff.width(), max_size_diff.height())
return control.compareImages(control_image, max_diff), control.report()

def _img_diff_error(self, response, headers, image, max_diff=100, max_size_diff=QSize(), unittest_data_path='control_images'):
def _img_diff_error(self, response, headers, image, max_diff=100, max_size_diff=QSize(), unittest_data_path='control_images', outputJpg=False):

extFile = 'png'
contentType = 'image/png'
if outputJpg:
extFile = 'jpg'
contentType = 'image/jpeg'

reference_path = unitTestDataPath(unittest_data_path) + '/qgis_server/' + image + '/' + image + '.png'
reference_path = unitTestDataPath(unittest_data_path) + '/qgis_server/' + image + '/' + image + '.' + extFile
self.store_reference(reference_path, response)

self.assertEqual(
headers.get("Content-Type"), "image/png",
"Content type is wrong: %s\n%s" % (headers.get("Content-Type"), response))
headers.get("Content-Type"), contentType,
"Content type is wrong: %s instead of %s\n%s" % (headers.get("Content-Type"), contentType, response))

test, report = self._img_diff(response, image, max_diff, max_size_diff)
test, report = self._img_diff(response, image, max_diff, max_size_diff, outputJpg)

with open(os.path.join(tempfile.gettempdir(), image + "_result.png"), "rb") as rendered_file:
with open(os.path.join(tempfile.gettempdir(), image + "_result." + extFile), "rb") as rendered_file:
encoded_rendered_file = base64.b64encode(rendered_file.read())
if not os.environ.get('ENCODED_OUTPUT'):
message = "Image is wrong\: rendered file %s/%s_result.png" % (tempfile.gettempdir(), image)
message = "Image is wrong\: rendered file %s/%s_result.%s" % (tempfile.gettempdir(), image, extFile)
else:
message = "Image is wrong\n%s\nImage:\necho '%s' | base64 -d >%s/%s_result.png" % (
report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image
message = "Image is wrong\n%s\nImage:\necho '%s' | base64 -d >%s/%s_result.%s" % (
report, encoded_rendered_file.strip().decode('utf8'), tempfile.gettempdir(), image, extFile
)

# If the failure is in image sizes the diff file will not exists.
if os.path.exists(os.path.join(tempfile.gettempdir(), image + "_result_diff.png")):
with open(os.path.join(tempfile.gettempdir(), image + "_result_diff.png"), "rb") as diff_file:
if os.path.exists(os.path.join(tempfile.gettempdir(), image + "_result_diff." + extFile)):
with open(os.path.join(tempfile.gettempdir(), image + "_result_diff." + extFile), "rb") as diff_file:
if not os.environ.get('ENCODED_OUTPUT'):
message = "Image is wrong\: diff file %s/%s_result_diff.png" % (tempfile.gettempdir(), image)
message = "Image is wrong\: diff file %s/%s_result_diff.%s" % (tempfile.gettempdir(), image, extFile)
else:
encoded_diff_file = base64.b64encode(diff_file.read())
message += "\nDiff:\necho '%s' | base64 -d > %s/%s_result_diff.png" % (
encoded_diff_file.strip().decode('utf8'), tempfile.gettempdir(), image
message += "\nDiff:\necho '%s' | base64 -d > %s/%s_result_diff.%s" % (
encoded_diff_file.strip().decode('utf8'), tempfile.gettempdir(), image, extFile
)

self.assertTrue(test, message)
Expand Down
9 changes: 7 additions & 2 deletions tests/src/python/test_qgsserver_accesscontrol.py
Expand Up @@ -202,8 +202,13 @@ def _post_restricted(self, data, query_string=None):
self._server.putenv("QGIS_PROJECT_FILE", '')
return result

def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
temp_image = os.path.join(tempfile.gettempdir(), "%s_result.png" % control_image)
def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize(), outputJpg=False):

extFile = 'png'
if outputJpg:
extFile = 'jpg'

temp_image = os.path.join(tempfile.gettempdir(), "%s_result.%s" % (control_image, extFile))

with open(temp_image, "wb") as f:
f.write(image)
Expand Down
16 changes: 16 additions & 0 deletions tests/src/python/test_qgsserver_wms_getprint.py
Expand Up @@ -90,6 +90,22 @@ def test_wms_getprint_basic(self):
r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Basic")

# Output JPEG
qs = "?" + "&".join(["%s=%s" % i for i in list({
"MAP": urllib.parse.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetPrint",
"TEMPLATE": "layoutA4",
"FORMAT": "jpeg",
"map0:EXTENT": "-33626185.498,-13032965.185,33978427.737,16020257.031",
"LAYERS": "Country,Hello",
"CRS": "EPSG:3857"
}.items())])

r, h = self._result(self._execute_request(qs))
self._img_diff_error(r, h, "WMS_GetPrint_Basic", outputJpg=True)

def test_wms_getprint_style(self):
# default style
qs = "?" + "&".join(["%s=%s" % i for i in list({
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 638650a

Please sign in to comment.