1

I have a geotiff that I've generated the way I'd like it displayed in QGIS. When I load the image as a raster layer, however, it automatically re-scales the pixel brightness values, and the image doesn't display the way I'd like. When using the GUI, I can click on the layer, then properties. I go to the histogram tab and click calculate histogram, then change the max to 255 (its typically a much smaller value to start, which makes the image look very "washed out"), and the image looks like I want it to..

I'm not sure why it changes it in the first place, but the same thing happens when I add the geotiff as a raster layer via my Python plugin. However, I can't figure out how to automate this via PyQGIS.. I'm using QGIS version 2.8.6-Wien..

If its important, I make the gtif prior to using QGIS via gdal_translate..

The question is - how can I use PyQGIS to perform this operation so the user doesn't have to do it? I have PyQGIS automatically adding the raster layer to the project already, its just the forcing it to display the full range of pixel values (within PyQGIS) that I am struggling with right now..

Also - its a 1 band image with a 'singlebandgray' renderer.


Update: the accepted answer pointed to a solution, but for the benefit of others who may be looking for a more direct answer to this particular issue, here is the code as modified to solve my issue:

newRasterLayer = QgsRasterLayer(gtifPathToFname, gtifFnameNoExten)
newRasterLayerProvider = newRasterLayer.dataProvider()

#Force 0 to map to black and 255 to map to white
#Note, this is for a single-band image, so only doing band 0
colorMapList = [QgsColorRampShader.ColorRampItem(0, QColor('#000000')), QgsColorRampShader.ColorRampItem(255, QColor('#FFFFFF'))]

#Jump through some hoops to get the colormap list defined above to
#be used by the new layer's renderer before it is added..
rasterShader = QgsRasterShader()
colorRamp = QgsColorRampShader()
colorRamp.setColorRampItemList(colorMapList)
colorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
rasterShader.setRasterShaderFunction(colorRamp)
pseudoRenderer = QgsSingleBandPseudoColorRenderer(newRasterLayer.dataProvider(), newRasterLayer.type(), rasterShader)
newRasterLayer.setRenderer(pseudoRenderer)
1

The default way a raster is displayed is dictated by settings in Settings -> Options -> Rendering and then scroll down to the Raster section. Setting the "limits (minimum/maximum)" option to "minimum/maximum" and the "Contrast Enhancement" to "Stretch to min/max" should mean that your raster comes in stretched in the way you want.

However, if you wanted to programme that into your python code then this question contains some code to extract the min and max values from the raster stats: How to update raster color ramp with new min/max values using PyQGIS?

  • I am sad to say that question was one of the first ones I looked at yesterday, but it didn't seem to apply.. With your pointing me back to it, I revisited and modified it to get it to do what I was trying to do.. It seems so complicated to do something which seems fairly simple, but it works! So thanks! – daroo Aug 1 '18 at 12:50
  • 1
    Glad it worked - the other option might be to apply a style file as suggested in this question: gis.stackexchange.com/questions/209950/… (I think that's programatically easier) – Ed Rollason Aug 1 '18 at 13:42
  • Hmm, that's an interesting approach too.. Oh well, the complication in the code isn't so bad in and of itself, its just that I never would have come up with that on my own.. shaders, ramp items, ramps, shader functions, pseudo-color renderers (my personal favorite), and renderers, all seem like a lot of craziness to just get an image to display the way it is stored in a gtif to begin with! :-) – daroo Aug 1 '18 at 13:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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