1

I simply need to load on QGIS a raster and a vector layer, and then I want to export a map where both of them are displayed, in particular with the vector layer on top of the raster one. This because the vector layer is a polygon and is a sort of "mask" for the raster image.

In other words I want to perform with python code the same thing I do from the QGIS GUI going on Project -> Import/Export -> Export Map As Image when I have my two layers selected on the map. I already tried this code:

from qgis.core import QgsProject, QgsMapRendererJob, QgsMapSettings
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QImage, QPainter
import os

layer_raster = QgsProject.instance().mapLayersByName("RUKHO")[0]
layer_shapefile = QgsProject.instance().mapLayersByName("mask")[0] 

width = layer_raster.width()
height = layer_raster.height()
image_size = QSize(width, height)

image = QImage(image_size, QImage.Format_ARGB32)
color = QColor(255,255,255,0)
image.fill(color.rgba())

p = QPainter()
p.begin(image)
p.setRenderHint(QPainter.Antialiasing)

ms = QgsMapSettings()
ms.setLayers([layer_raster, layer_shapefile])
ms.setOutputSize(image_size)

rect = QgsRectangle(ms.fullExtent())
rect.scale(1.1)
ms.setExtent(rect)

#ms.setExtent(layer_raster.extent())

render = QgsMapRendererCustomPainterJob(ms, p)
render.renderSynchronously()
render.start()
render.waitForFinished()
p.end()

output_file = "C:/Users/borri/Master Thesis/ciao.jpeg"  
image.save(output_file, "jpeg")

I obtain a full white image

If I change the "extent part using the commented line and commenting the others:

# rect = QgsRectangle(ms.fullExtent())
# rect.scale(1.1)
# ms.setExtent(rect)

ms.setExtent(layer_raster.extent())

Then my QGIS app crashes and it closes without any message, not creating any image as output.

I thought about putting "layer_raster.extent()" only because I want an output with the same size as the raster layer.

I also tried something with the mapCanvas but the result is useless again. I thought that the line

ms.setLayers([layer_raster, layer_shapefile])

should tell which layers I want to export. But it seems not to be like that because with other tries I obtained an image showing ONLY the raster layer, without the vector on top.

Please help me I only found solutions with codes that don't work for me.

1 Answer 1

2

The easiest way to fix your code is to take the QgsMapSettings object from the current project canvas.

Here is the code that works for me in the python console in QGIS:

from qgis.core import QgsProject, QgsMapRendererJob, QgsMapSettings
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QImage, QPainter
import os

layer_raster = QgsProject.instance().mapLayersByName("RUKHO")[0]
layer_shapefile = QgsProject.instance().mapLayersByName("mask")[0] 

width = layer_raster.width()
height = layer_raster.height()
image_size = QSize(width, height)

image = QImage(image_size, QImage.Format_ARGB32)
color = QColor(255,255,255,0)
image.fill(color.rgb())

p = QPainter()
p.begin(image)
p.setRenderHint(QPainter.Antialiasing)

canvas = iface.mapCanvas()

ms = canvas.mapSettings()
ms.setOutputSize(image_size)

rect = QgsRectangle(ms.fullExtent())
rect.scale(1.1)
ms.setExtent(rect)

render = QgsMapRendererCustomPainterJob(ms, p)
render.renderSynchronously()
render.start()
render.waitForFinished()
p.end()

output_file = "C:/Users/borri/Master Thesis/ciao.jpeg"  
image.save(output_file, "jpeg")

Lines that fix the problem:

canvas = iface.mapCanvas()
ms = canvas.mapSettings()

Instead of:

ms = QgsMapSettings()
ms.setLayers([layer_raster, layer_shapefile])

Layers do not need to be added because they are open in your project. And they are on the current canvas.

1
  • It worked! Thank you very very much! Aug 8, 2023 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.