Package gavo :: Package utils :: Module imgtools
[frames] | no frames]

Source Code for Module gavo.utils.imgtools

 1  """ 
 2  Some miscellaneous helpers for making images and such. 
 3   
 4  As this may turn into a fairly expensive import, this should *not* be imported 
 5  by utils.__init__.   Hence, none of these functions are in gavo.api or 
 6  gavo.utils. 
 7  """ 
 8   
 9  #c Copyright 2008-2019, the GAVO project 
10  #c 
11  #c This program is free software, covered by the GNU GPL.  See the 
12  #c COPYING file in the source distribution. 
13   
14   
15  from cStringIO import StringIO 
16   
17  from PIL import Image 
18  import numpy 
19   
20   
21 -def _normalizeForImage(pixels, gamma):
22 """helps jpegFromNumpyArray and friends. 23 """ 24 pixels = numpy.flipud(pixels) 25 pixMax, pixMin = numpy.max(pixels), numpy.min(pixels) 26 return numpy.asarray(numpy.power( 27 (pixels-pixMin)/(pixMax-pixMin), gamma)*255, 'uint8')
28 29
30 -def jpegFromNumpyArray(pixels, gamma=0.25):
31 """returns a normalized JPEG for numpy pixels. 32 33 pixels is assumed to come from FITS arrays, which are flipped wrt to 34 jpeg coordinates, which is why we're flipping here. 35 36 The normalized intensities are scaled by v^gamma; we believe the default 37 helps with many astronomical images 38 """ 39 f = StringIO() 40 Image.fromarray(_normalizeForImage(pixels, gamma) 41 ).save(f, format="jpeg") 42 return f.getvalue()
43 44
45 -def colorJpegFromNumpyArrays(rPix, gPix, bPix, gamma=0.25):
46 """as jpegFromNumpyArray, except a color jpeg is built from red, green, 47 and blue pixels. 48 """ 49 pixels = numpy.array([ 50 _normalizeForImage(rPix, gamma), 51 _normalizeForImage(gPix, gamma), 52 _normalizeForImage(bPix, gamma)]).transpose(1,2,0) 53 54 f = StringIO() 55 Image.fromarray(pixels, mode="RGB").save(f, format="jpeg") 56 return f.getvalue()
57 58
59 -def scaleNumpyArray(arr, destSize):
60 """returns the numpy array arr scaled down to approximately destSize. 61 """ 62 origWidth, origHeight = arr.shape 63 size = max(origWidth, origHeight) 64 scale = max(1, size//destSize+1) 65 destWidth, destHeight = origWidth//scale, origHeight//scale 66 67 # There's very similar code in fitstools.iterScaledRows 68 # -- it would be nice to refactor things so this can be shared. 69 img = numpy.zeros((destWidth, destHeight), 'float32') 70 71 for rowInd in range(destHeight): 72 wideRow = (numpy.sum( 73 arr[:,rowInd*scale:(rowInd+1)*scale], 1, 'float32' 74 )/scale)[:destWidth*scale] 75 # horizontal scaling via reshaping to a matrix and then summing over 76 # its columns. 77 newRow = numpy.sum( 78 numpy.transpose(wideRow.reshape((destWidth, scale))), 0)/scale 79 img[:,rowInd] = newRow 80 81 return img
82 83
84 -def getScaledPNG(srcFile, newWidth):
85 """returns a PNG string that is a scaled version of an image in srcFile. 86 87 srcFile must correspond to something that PIL can read. Since scaling 88 really sucks for non-RGB images, we unconditionally convert whatever we 89 get to 3-band RGB. 90 """ 91 im = Image.open(srcFile).convert("RGB") 92 scale = newWidth/float(im.size[0]) 93 scaled = im.resize((newWidth, int(im.size[1]*scale)), Image.ANTIALIAS) 94 f = StringIO() 95 scaled.save(f, format="png") 96 return f.getvalue()
97