def _apply_postprocessing(self, image, user): size = image.size alpha = 220 alphaf = alpha / 255.0 stops = [ (2.0, image_utils.parse_rgb(user.color_primary, alpha), image_utils.parse_rgb(user.color_secondary, alpha)) ] bg = image.convert("L").convert("RGB") fg = image_utils.get_gradient_image(size, stops) # combine bg and fg layers via screen blend mode with 75% opacity on fg layer # see this wikipedia article for a description of screen blend mode: # http://en.wikipedia.org/wiki/Blend_modes output = Image.new("RGB", size) data = [] blend_func = lambda b, f: image_utils.clamp(255.0 - (((255.0 - alphaf * f) * (255.0 - b)) / 255.0)) for y in xrange(size[1]): for x in xrange(size[0]): pos = (x, y) bg_px = bg.getpixel(pos) fg_px = fg.getpixel(pos) color = tuple(blend_func(bg_px[i], fg_px[i]) for i in xrange(len(bg_px))) data.append(color) output.putdata(data) return output
def create_gradient(width, height, user): alpha = 255 stops = [( 2.0, image_utils.parse_rgb(user.color_primary, alpha), image_utils.parse_rgb(user.color_secondary, alpha) )] return image_utils.get_gradient_image((width, height), stops)