def make(src_path, out_path): src = Image.open(src_path) src = src.copy() (srcr, srcg, srcb, srca) = src.split() white = ImageChops.constant(src, 255) outr = cast_gradation(srcr, 0, 90) outg = cast_gradation(srcg, 0, 90) outb = cast_gradation(srcb, 0, 90) outa = srca.copy() outr = ImageChops.composite(srcr, white, srca) outg = ImageChops.composite(srcg, white, srca) outb = ImageChops.composite(srcb, white, srca) (shadow_a, shadow) = make_inset_shadow(srca) outr = ImageChops.subtract(outr, shadow, 1, 0) outg = ImageChops.subtract(outg, shadow, 1, 0) outb = ImageChops.subtract(outb, shadow, 1, 0) outa = ImageChops.lighter(outa, shadow_a) (highlight_a, highlight) = make_highlight(srca) outa = ImageChops.lighter(outa, highlight) outa = ImageChops.subtract(outa, ImageChops.constant(outa, 25), 1, 0) out = Image.merge('RGBA', (outr, outg, outb, outa)) out.save(out_path)
def draw_marker(width, height, offset, filename): im = Image.new('L', (128, 256), 255) draw = ImageDraw.Draw(im) cx = (im.size[0] / 2) + 1.5 cy = (im.size[1] / 4) + 1.5 radius = width * 4.0 / 2.0 offset = int(offset * 4.0) for thickness, colour in ((0, 0x60), (4, 0xE0)): ol = im.copy() r = radius + 0.5 - thickness draw.ellipse((cx - r, cy - r, cx + r, cy + r), fill=colour) x1 = offset + 0.5 - (thickness * 1.5) y1 = (height * 4.0) + 0.5 - (width * 2.0) - (thickness * 2.0) draw.polygon((cx + 0.5, cy + y1, cx - 0.5, cy + y1, cx - x1, cy + 16.5, cx + x1, cy + 16.5), fill=colour) del draw im = im.resize((im.size[0] / 4, im.size[1] / 4), Image.ANTIALIAS) ol = ol.resize(im.size, Image.ANTIALIAS) mask = Image.eval(ol, lambda x: (0, 255)[x < 210]) im = Image.composite(im, ImageChops.constant(im, 0), mask) im = im.crop(im.getbbox()) im.save(filename, transparency=0)
view = im.view(0, 0, width, height) # x,y,width,height #print "saving ", map_uri #view.save(map_uri,'png') #'save' the image in a string imgStr = view.tostring('png') # reopen the saved image with PIL to count the color # if 1, the pic is empty #img = Image.open(map_uri) # kind of StringIO() for images instead: imgParser = ImageFile.Parser() imgParser.feed(imgStr) img = imgParser.close() if len(img.getcolors()) == 1: print "empty file not saved", map_uri #delete the pic file if empty #os.remove(map_uri) else: # Crop the file to its smaller extent # Cropping the pic allow a much concise html page formatting, # use CSS for the rest img256 = img.convert('L') imgbg = ImageChops.constant(img256, img256.getpixel((0, 0))) box = ImageChops.difference(img256, imgbg).getbbox() out = img.crop(box) print "saving ", map_uri out.save(map_uri)
def renderLegendElement(sourceFile, elementType, tagList, zoom, imageWidth, map_uri): """ # 'Fake' load a map to use mapnik libxml2 support for large xml files mSource = mapnik.Map(1,1) mapnik.load_map(mSource,sourceFile) inputstylesheet=mapnik.save_map_to_string(mSource) """ # serialize map file with external entities included inputstylesheet = etree.tostring(etree.parse(sourceFile)) # the mapfile (stylesheet made only for legend element rendering # is returned as a string, no file is written on disk # then use mapnik.load_map_from_string mapfile = create_legend_stylesheet(inputstylesheet) # create a new element, which return its bbox and an osm file as # a string osmStr, bound = createOsmElement(elementType, tagList, zoom) # create a named temporary file, mapnik needs a real file # we cannot pass a StringIO nor a string, nor a unnammed # temporary file osmFile = tempfile.NamedTemporaryFile(mode='w+t') osmFile.write(osmStr) #write the osm file osmFile.seek(0) #rewind #--------------------------------------------------- # Set up projection # long/lat in degrees, aka ESPG:4326 and "WGS 84" lonlat = mapnik.Projection('+proj=longlat +datum=WGS84') #bbbox =(lon,lat,maxlon,maxlat) ratio = abs((bound[2] - bound[0]) / (bound[3] - bound[1])) width = imageWidth height = int(width / ratio * 1) # add +1 if highway=path looks blurry FIXME m = mapnik.Map(width, height) mapnik.load_map_from_string(m, mapfile) m.srs = lonlat.params() for l in m.layers: l.datasource = Osm(file=osmFile.name) l.srs = lonlat.params() # uncomment this line to save the mapfile on disk, remember to # NEVER show this file to a stylesheet maintainer: #save_map(m,'mapfile.xml') # render the element and save to disk bbox =lonlat.forward(mapnik.Envelope(mapnik.Coord(bound[0],bound[1]),\ mapnik.Coord(bound[2],bound[3]))) m.zoom_to_box(bbox) im = mapnik.Image(width, height) mapnik.render(m, im) osmFile.close() # closing the datasource view = im.view(0, 0, width, height) # x,y,width,height #print "saving ", map_uri #view.save(map_uri,'png') #'save' the image in a string imgStr = view.tostring('png') # reopen the saved image with PIL to count the color # if 1, the pic is empty #img = Image.open(map_uri) # kind of StringIO() for images instead: imgParser = ImageFile.Parser() imgParser.feed(imgStr) img = imgParser.close() if len(img.getcolors()) == 1: print "empty file not saved", map_uri #delete the pic file if empty #os.remove(map_uri) else: # Crop the file to its smaller extent # Cropping the pic allow a much concise html page formatting, # use CSS for the rest img256 = img.convert('L') imgbg = ImageChops.constant(img256, img256.getpixel((0, 0))) box = ImageChops.difference(img256, imgbg).getbbox() out = img.crop(box) print "saving ", map_uri out.save(map_uri) return True
#view.save(map_uri,'png') #'save' the image in a string imgStr=view.tostring('png') # reopen the saved image with PIL to count the color # if 1, the pic is empty #img = Image.open(map_uri) # kind of StringIO() for images instead: imgParser=ImageFile.Parser() imgParser.feed(imgStr) img = imgParser.close() if len(img.getcolors()) == 1: print "empty file not saved", map_uri #delete the pic file if empty #os.remove(map_uri) else: # Crop the file to its smaller extent # Cropping the pic allow a much concise html page formatting, # use CSS for the rest img256=img.convert('L') imgbg=ImageChops.constant(img256,img256.getpixel((0,0))) box=ImageChops.difference(img256, imgbg).getbbox() out=img.crop(box) print "saving ", map_uri out.save(map_uri)
def renderLegendElement(sourceFile, elementType, tagList, zoom, imageWidth, map_uri): """ # 'Fake' load a map to use mapnik libxml2 support for large xml files mSource = mapnik.Map(1,1) mapnik.load_map(mSource,sourceFile) inputstylesheet=mapnik.save_map_to_string(mSource) """ # serialize map file with external entities included inputstylesheet=etree.tostring(etree.parse(sourceFile)) # the mapfile (stylesheet made only for legend element rendering # is returned as a string, no file is written on disk # then use mapnik.load_map_from_string mapfile = create_legend_stylesheet(inputstylesheet) # create a new element, which return its bbox and an osm file as # a string osmStr, bound = createOsmElement(elementType, tagList, zoom) # create a named temporary file, mapnik needs a real file # we cannot pass a StringIO nor a string, nor a unnammed # temporary file osmFile = tempfile.NamedTemporaryFile(mode='w+t') osmFile.write(osmStr) #write the osm file osmFile.seek(0) #rewind #--------------------------------------------------- # Set up projection # long/lat in degrees, aka ESPG:4326 and "WGS 84" lonlat = mapnik.Projection('+proj=longlat +datum=WGS84') #bbbox =(lon,lat,maxlon,maxlat) ratio= abs((bound[2]-bound[0])/(bound[3]-bound[1])) width = imageWidth height = int(width/ratio*1) # add +1 if highway=path looks blurry FIXME m = mapnik.Map(width,height) mapnik.load_map_from_string(m,mapfile) m.srs = lonlat.params() for l in m.layers: l.datasource = Osm(file=osmFile.name) l.srs = lonlat.params() # uncomment this line to save the mapfile on disk, remember to # NEVER show this file to a stylesheet maintainer: #save_map(m,'mapfile.xml') # render the element and save to disk bbox =lonlat.forward(mapnik.Envelope(mapnik.Coord(bound[0],bound[1]),\ mapnik.Coord(bound[2],bound[3]))) m.zoom_to_box(bbox) im = mapnik.Image(width,height) mapnik.render(m, im) osmFile.close() # closing the datasource view = im.view(0,0,width,height) # x,y,width,height #print "saving ", map_uri #view.save(map_uri,'png') #'save' the image in a string imgStr=view.tostring('png') # reopen the saved image with PIL to count the color # if 1, the pic is empty #img = Image.open(map_uri) # kind of StringIO() for images instead: imgParser=ImageFile.Parser() imgParser.feed(imgStr) img = imgParser.close() if len(img.getcolors()) == 1: print "empty file not saved", map_uri #delete the pic file if empty #os.remove(map_uri) else: # Crop the file to its smaller extent # Cropping the pic allow a much concise html page formatting, # use CSS for the rest img256=img.convert('L') imgbg=ImageChops.constant(img256,img256.getpixel((0,0))) box=ImageChops.difference(img256, imgbg).getbbox() out=img.crop(box) print "saving ", map_uri out.save(map_uri) return True