|

PyQGIS: Render (Print/Save) a Layer as an Image

This tutorial will teach you how to render (print or save) a QGIS layer as an image using the PyQGIS Python API. Automating layer rendering can be very useful to create and save visualizations that have consistent styling, extent and format.

The first thing you need to do is create a QImage. Here we create an image with the size 800 x 800 pixels.

# create image
img = QImage(QSize(800, 800), QImage.Format_ARGB32_Premultiplied)

Now you can set the background color of the image using red, green, blue, and alpha values. Alpha is the transparency. The numbers below create an image with a fully opaque, white background. If the alpha value (fourth number) was 0 it would be fully transparent. Once the background color is set, fill the image with it.

# set background color
color = QColor(255, 255, 255, 255)
img.fill(color.rgba())

The next thing you need is a painter to paint the image. First, initialize the painter. Then begin paining the image. Using antialiasing helps prevent the image from looking pixelated on the edges.

# create painter
p = QPainter()
p.begin(img)
p.setRenderHint(QPainter.Antialiasing)

With the painter set up, we now need to set up the layer for it to paint. First get the map setting from QGIS, and set the background color to be the same as the background color for the painter.

Next, get the layer you want to display. The code below retrieves the layer with the name ‘layer name’. Then set the map settings layers. Note: you can add multiple layers to map settings by passing more than one layer in the list.

# create map settings
ms = QgsMapSettings()
ms.setBackgroundColor(color)

# set layers to render
layer = QgsProject.instance().mapLayersByName('layer name')
ms.setLayers([layer[0]])

The next step is to define the area we want to print. For this example we’ll print the entire extent of the layers in the map settings. We’ll also slightly increase the size of the rectangle by a factor of 1.1. Then, set the map settings extent. Finally, set the map settings output size to equal that of the image we are creating.

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

# set ouptut size
ms.setOutputSize(img.size())

Now your ready to create the final image. Create a QGIS painter job and give it the map settings and the painter. Remember that we set the painter to paint our image at the beginning of the code. Start the painter job and end it once it has finished.

# setup qgis map renderer
render = QgsMapRendererCustomPainterJob(ms, p)
render.start()
render.waitForFinished()
p.end()

The last thing to do is save the image. And you’re done!

# save the image
img.save('C:/temp/test_render.png')

Here is the complete code block we created. Watch the video below for a step-by-step demonstration of the process.

# create image
img = QImage(QSize(800, 800), QImage.Format_ARGB32_Premultiplied)

# set background color
color = QColor(255, 255, 255, 255)
img.fill(color.rgba())

# create painter
p = QPainter()
p.begin(img)
p.setRenderHint(QPainter.Antialiasing)

# create map settings
ms = QgsMapSettings()
ms.setBackgroundColor(color)

# set layers to render
layer = QgsProject.instance().mapLayersByName('stream_order')
ms.setLayers([layer[0]])

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

# set ouptut size
ms.setOutputSize(img.size())

# setup qgis map renderer
render = QgsMapRendererCustomPainterJob(ms, p)
render.start()
render.waitForFinished()
p.end()

# save the image
img.save('C:/temp/test_render.png')

Similar Posts