source: cows/trunk/cows/service/imps/pywms/render_imp.py @ 5399

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/service/imps/pywms/render_imp.py@5399
Revision 5399, 5.2 KB checked in by domlowe, 12 years ago (diff)

Changing PIL imports in cows

Line 
1# BSD Licence
2# Copyright (c) 2009, Science & Technology Facilities Council (STFC)
3# All rights reserved.
4#
5# See the LICENSE file in the source distribution of this software for
6# the full license text.
7
8"""
9Implementation of grid rendering classes.
10
11@author: Stephen Pascoe
12"""
13
14from view import GridRenderer
15try: 
16    from PIL import Image, ImageColor
17except ImportError:
18    import Image, ImageColor
19
20import numpy as N
21import logging
22from matplotlib import cm, colors
23
24logger = logging.getLogger(__name__)
25
26class RGBARenderer(GridRenderer):
27    """Creates an RGBA PNG with a selectable matplotlib colour scale.
28    """
29
30    mimeType = 'image/png'
31
32    def __init__(self, varmin, varmax):
33        self.varmin = varmin
34        self.varmax = varmax
35        self._norm = colors.normalize(varmin, varmax)
36
37    def renderColourbar(self, width, height, cmap, isVertical=True):
38        a = N.arange(0, 1.0, 1.0/256)
39        if isVertical:
40            a = a[-1::-1]
41            shape = (1, 256)
42        else:
43            shape = (256, 1)
44        cbar = (cmap(a) * 255).astype('b').tostring()
45        img = Image.frombuffer("RGBA", shape, cbar, "raw", "RGBA", 0, 1)
46        img = img.resize((width, height))
47        return img
48
49    def renderGrid(self, grid, bbox, width, height, cmap):
50        cmap.set_bad('#ffffff', 0.0)
51
52        logger.debug('grid %s, %s, %s, %s, %s, %s, %s, %s' %
53                    (grid.x0, grid.y0, grid.dx, grid.dy, grid.nx, grid.ny,
54                     grid.ix, grid.iy))
55#        logger.debug('bbox %s' % (bbox,))
56#        logger.debug('width %s'%width)
57#        logger.debug('height %s'%height)
58
59        # Get a pixel = grid-box image for the grid
60        img = self._grid2Img(grid, cmap)
61
62        logger.debug('image size%s' %str(img.size))
63        # Calculate the pixel-size of a grid box
64       
65       
66        numDeg_X=grid.dx*grid.nx
67        numDeg_Y=grid.dy*grid.ny
68        pxPerDeg_x=float(width)/numDeg_X
69        pxPerDeg_y=float(height)/numDeg_Y
70# modified from this:
71#        pxPerDeg_x = float(width) / (bbox[2] - bbox[0])
72#        pxPerDeg_y = float(height) / (bbox[3] - bbox[1])
73        pxPerGrid_x = grid.dx * pxPerDeg_x
74        pxPerGrid_y = grid.dy * pxPerDeg_y
75
76        # Scale Img to the right size
77        logger.debug('resizing to %s in X and %s in y'%(abs(pxPerGrid_x * grid.nx),abs(pxPerGrid_y * grid.ny)))
78        img = img.resize(((abs(pxPerGrid_x * grid.nx),
79                           abs(pxPerGrid_y * grid.ny))))
80        #!NO: We assume the grid points represent the centre of the grid boxes
81        #!NO: therefore we can calculate the upper-left position of the image
82        # Adapted so that the grid points represent the lower left corner of grid boxes
83
84#       
85#       
86#        # Find top-left corner of grid
87#        if grid.dx > 0:
88#            leftX = grid.x0
89#        else:
90#            leftX = grid.x0 + (grid.dx * (grid.nx - 1))
91#        if grid.dy > 0:
92#            topY = grid.y0 + (grid.dy * (grid.ny - 1))
93#        else:
94#            topY = grid.y0
95#
96#        logger.debug('top-left = %s x, %s y' % (leftX, topY))
97#
98#        # Find pixel position of top left centre grid box
99#        cx = width * ((leftX - bbox[0])/ (bbox[2] - bbox[0]))
100#        cy = height * ((bbox[3] - topY) / (bbox[3] - bbox[1]))
101#        logger.debug('top-left centre pixel = %s x, %s y' % (cx, cy))
102#
103#        # Apply half width of grid box
104#        ox = int(cx - pxPerGrid_x / 2)
105#        oy = int(cy - pxPerGrid_y / 2)
106##        ox,oy = int(cx), int(cy-pxPerGrid_y)
107#        logger.debug('Offset: %s x, %s y' % (ox, oy))
108
109
110        # Paste the grid image into the tile image
111        tileImg = Image.new('RGBA', (width, height))
112        #logger.debug('Pasting image img%s into tileImg%s at (%s,%s)' % (img.size, tileImg.size, ox, oy))
113#        tileImg.paste(img, (ox, oy))
114        tileImg.paste(img, (0,0))
115        return tileImg
116   
117
118
119    def _grid2Img(self, grid, cmap):
120        """Returns the grid as an image where each pixel is one grid box.
121        """
122        a = self._norm(grid.value)
123       
124        img_buf = (cmap(a) * 255).astype('b')
125        # This code assumes the axis ordering is either (y, x, time) or (x, y, time)
126        if min(grid.iy, grid.ix) != 0 and max(grid.iy, grid.ix) != 1:
127            raise ValueError("X and Y must be the first 2 dimensions!")
128        if grid.iy < grid.ix:
129            yxOrdering = True
130        else:
131            yxOrdering = False
132           
133        #fix for extreme zoom errors 
134        try:
135            img = Image.frombuffer("RGBA", img_buf.shape[1::-1], img_buf.tostring(), "raw", "RGBA", 0, 1)
136        except ValueError:
137            if len(grid.value.shape) == 1: 
138                imageshape=(grid.value.shape[0], 1)   
139                img = Image.frombuffer("RGBA", imageshape, img_buf.tostring(), "raw", "RGBA", 0, 1)
140#        img.save('/tmp/raw1.png')
141
142        # Rotate if axis order is x, y
143        if not yxOrdering:
144            img = img.transpose(Image.ROTATE_90)
145        # Flip if x or y are ordered the wrong way
146        if grid.dy > 0:
147            logger.debug('Flipping y')
148            img = img.transpose(Image.FLIP_TOP_BOTTOM)
149        if grid.dx < 0:
150            logger.debug('Flipping x')
151            img = img.transpose(Image.FLIP_LEFT_RIGHT)
152        return img
153
Note: See TracBrowser for help on using the repository browser.