Bug report #9101
Raster artefact in composer pdf export
Status: | Closed | ||
---|---|---|---|
Priority: | Normal | ||
Assignee: | - | ||
Category: | Map Composer/Printing | ||
Affected QGIS version: | 2.0.1 | Regression?: | No |
Operating System: | Easy fix?: | No | |
Pull Request or Patch supplied: | No | Resolution: | |
Crashes QGIS or corrupts data: | No | Copied to github as #: | 17746 |
Description
When exporting composer with raster image to pdf it leaves an artefact around the edge of the image.
See attached raster and workspace and pdf output. Workspace contains composer window.
Raster was georeferenced which resulting it it being turned through ~90°, but is in the same projection as the project.
With a higher resolution raster the issue is more pronounced. The artefact does not exist when exported to png.
History
#1 Updated by Radim Blazek about 11 years ago
It seems that if there are NULL values in the raster a mask representing those values (transparent) is written to PDF as an object and that mask is specified in the raster object as 'Mask'.
Unfortunately such PDF displayed in Acrobar Reader (9.5.3) shows those artefacts. Okular (PDF Backend 0.5) shows different problems (artefact on the right and image not fully masked.
If I remove the Mask from the image in PDF the artefacts disappear, but NULL values are rendered black.
That is out of our control AFAICT. We simply call QPainter::drawImage() and the rest is in hands of Qt and Acrobat Reader.
A workaround should be to use only rasters without NULL values, transparency and reprojection (which all result in transparent pixels).
We have to verify if it is really Qt problem and why it works in 1.8. Maybe it was introduced with blending modes?
#2 Updated by Radim Blazek almost 11 years ago
Images are written to PDF as JPEG. Because JPEG does not support transparency it is written as another mask image and specified as '/Mask' of main image.
The problem is that Acrobat Reader does not mask correctly raster images and margin of pixels under the mask is visible. If a color of those pixels is not the same as background the margin appears as artefact.
Attached is demo test.py which produces test.pdf containing 10x10 image filled by 255,255,255,255 and half set to 0,0,0,0. test.png is snapshot of test.pdf visualized in Acrobat Reader 9.5.3. test.jpeg is main image stream extracted from test.pdf. test.pdf is rendered correctly in Okular/Debian.
While QGIS 1.8 is using for transparent pixels qRgba( 255, 255, 255, 0 ), QGIS 2.0 is using qRgba( 0, 0, 0, 0 ) (QgsRasterRenderer::NODATA_COLOR). Unfortunately changing NODATA_COLOR to qRgba( 255, 255, 255, 0 ) (5181cbe) does not help! Transparent pixels are still written as black to JPEG stream in PDF (white in QGIS 1.8). I tried also ARGB32 instead of ARGB32_Premultiplied but it has no effect.
So the question is why in QGIS 2.0 qRgba( 255, 255, 255, 0 ) pixels are written to PDF JPEG stream as black while in 1.8 as white.
#3 Updated by Radim Blazek almost 11 years ago
- Status changed from Open to Closed
Fixed in changeset 330b46b8a9291fd81d88f6ff8092003c7aac8234.
#4 Updated by Radim Blazek almost 11 years ago
There was raster reprojector after renderer also using color 0,0,0,0 for no data.
#5 Updated by marisn - almost 11 years ago
- Operating System deleted (
Ubuntu) - OS version deleted (
12.04) - Status changed from Closed to Reopened
- File QGIS_composer_export_raster_fail.jpg added
Radim, unfortunately your solution breaks exporting to PNG and JPEG images. Didn't test with other formats. See attached screenshot with on-screen and exported map. As it's visible - there are artefacts for both - vector and raster data.
Please, try to find other solution as 5181cbed155fc31b71d675b948b2caf242e2cbcf currently is real breaker.
#6 Updated by Radim Blazek almost 11 years ago
Could you create simple test project?
Does it work OK in 1.8?
#7 Updated by marisn - almost 11 years ago
- File QGIS_transparency_fail.zip added
- File transp_fail.jpg added
I bisected problem to the commit I indicated.
General test case:
1) Vector data set;
2) Raster data set with some NULL values;
3) Arrange raster to be on top of vector
4) Set vector colour to any dark colour (black is fine);
5) Map transparency set to non-0 value in Map compositor;
6) Export to jpg or png.
(or just download, unzip, go to map composer and File->Save as Image->format=png)
Observe that also a transparent vertical strip that equals height of raster data set appears on the left hand side of raster.
#8 Updated by Radim Blazek almost 11 years ago
The margin on the left (potentially also right) is another issue, it just became apparent with no data color change, I think.
What do you call exactly 'artefacts'? I only see the wrong color of the vector which should be dark red instead of cyan. Is it the problem you are referring to or there are others?
#9 Updated by marisn - almost 11 years ago
Radim Blazek wrote:
The margin on the left (potentially also right) is another issue, it just became apparent with no data color change, I think.
What do you call exactly 'artefacts'? I only see the wrong color of the vector which should be dark red instead of cyan. Is it the problem you are referring to or there are others?
Yes, margins on edges could be a different issue. Could there be raster/vector alignment issue?
Sorry, at the beginning I couldn't understand the cause of this error. There is only one wrong thing - after your change, compositing of no-data areas with background (vector, raster) isn't working properly (wrong colours on raster can be observed on the first screenshot I attached).
#10 Updated by Radim Blazek almost 11 years ago
For raster artefacts on left / right border I have created new issue #9343.
#11 Updated by Radim Blazek almost 11 years ago
- Status changed from Reopened to Closed
Fixed in changeset 00efc467844fc710e12a4ab7a64b3fc76b133ad2.
#12 Updated by Radim Blazek almost 11 years ago
Summary:
- QGIS was working well, writing RGBA 0,0,0,0 for transparent pixels, but there is a bug in Acroba Reader so that the black RGB part of those pixels is partially visible.
- It was fixed by using 255,255,255,0 but that introduced other problems, because we are using Format_ARGB32_Premultiplied for which the result is undefined if RR, GG or BB are greater than AA
- Switched back to 0,0,0,0 and added format conversion to Format_ARGB32 and resetting of pixels from 0,0,0,0 to 255,255,255,0 for PDF output in raster drawer.