[GRASS-dev] [GRASS GIS] #3156: Cannot export GRASS raster map using r.out.png (crashes on windows)

GRASS GIS trac at osgeo.org
Thu Sep 13 13:43:00 PDT 2018


#3156: Cannot export GRASS raster map using r.out.png (crashes on windows)
----------------------+---------------------------------------------
  Reporter:  spawley  |      Owner:  grass-dev@…
      Type:  defect   |     Status:  new
  Priority:  normal   |  Milestone:  7.0.7
 Component:  Raster   |    Version:  7.0.4
Resolution:           |   Keywords:  r.out.png, wingrass, g.ppmtopng
       CPU:  x86-64   |   Platform:  MSWindows 7
----------------------+---------------------------------------------
Changes (by wenzeslaus):

 * keywords:  r.out.png, wingrass => r.out.png, wingrass, g.ppmtopng


Comment:

 Replying to [comment:12 neteler]:
 > How about making it "simply" a Python wrapper around r.out.gdal with PNG
 etc hardcoded?

 That would solve only `r.out.png` not `g.ppmtopng` or PNG driver (if it is
 broken (please test)).

 Additionally, `r.out.gdal` and `r.out.png` outputs are not identical and
 `r.out.png` always gave me a more expected output, for example
 transparency works.

 However, your suggestion makes sense. An alternative I used was `d.rast`.
 That again gives different result - the pixels are resampled so that when
 ns and ew resolutions don't match you get the right shape unlike with
 `r.out.gdal` or `r.out.png` where you get the result stretched when viewed
 without georeferencing.

 The code for `d.rast` is below. AFAIU `r.out.gdal` would require setting
 transparency; code for a simple but limited way to do that is attached
 too. I'm thinking about adding some of these functions to the Python
 library.

 {{{
 #!python
 def set_rendering_environment(width, height, filename, transparent,
                               backgroud_color='ffffff', driver='cairo',
                               compression=None, env=None):
     # if parameter not provided (but allow for empty dictionary)
     if env is None:
         env = os.environ
     env['GRASS_RENDER_WIDTH'] = str(width)
     env['GRASS_RENDER_HEIGHT'] = str(height)
     env['GRASS_RENDER_IMMEDIATE'] = driver
     env['GRASS_RENDER_BACKGROUNDCOLOR'] = backgroud_color
     env['GRASS_RENDER_TRUECOLOR'] = "TRUE"
     if transparent:
         env['GRASS_RENDER_TRANSPARENT'] = "TRUE"
     else:
         env['GRASS_RENDER_TRANSPARENT'] = "FALSE"
     if compression:
         env['GRASS_RENDER_FILE_COMPRESSION'] = str(compression)
     env['GRASS_RENDER_FILE'] = str(filename)


 def get_region():
     gregion_out = gs.read_command('g.region', flags='pg')
     region = gs.parse_key_val(gregion_out, sep='=')
     return {'east': float(region['e']), 'north': float(region['n']),
             'west': float(region['w']), 'south': float(region['s']),
             'rows': int(region['rows']), 'cols': int(region['cols']),
             'nsres': float(region['nsres']),
             'ewres': float(region['ewres'])}


 region = get_region()
 if region['nsres'] > region['ewres']:
     # oversample in rows, do not loose columns
     width = region['cols']
     height = region['rows'] * (region['nsres'] / region['ewres'])
 else:
     # oversample in columns, do not loose rows
     width = region['cols'] * (region['ewres'] / region['nsres'])
     height = region['rows']
 if 't' in routpng_flags:
     transparent = True
 else:
     transparent = False
 set_rendering_environment(width=width, height=height,
                           filename=output_file,
                           transparent=True, driver='cairo',
                           compression=compression)
 }}}

 {{{
 #!python
         try:
                 from PIL import Image
         except ImportError:
                 gcore.warning(_("Cannot save transparency because"
                                 " PIL library is missing."))
                 return
         if rgb == 'white':
                 rgb = (255, 255, 255)
         elif rgb == 'black':
                 rgb = (0, 0, 0)
         img = Image.open(filename)
         img = img.convert("RGBA")
         old_data = img.getdata()
         new_data = []
         for item in old_data:
                 if item[0] == rgb[0] and item[1] == rgb[1] and item[2] ==
 rgb[2]:
                         new_data.append((255, 255, 255, 0))
                 else:
                         new_data.append(item)
         img.putdata(new_data)
         img.save(filename, "PNG")
 }}}

 A step further would be a `r.export.png` module which would, with whatever
 backend, create a georeferenced PNG but in a SRS provided by the user.

-- 
Ticket URL: <https://trac.osgeo.org/grass/ticket/3156#comment:13>
GRASS GIS <https://grass.osgeo.org>



More information about the grass-dev mailing list