def stitch(im, pixelation=12): im = im.convert('RGB') im = util.resize_jam_background(im) width, height = im.size # pixelate im = im.resize((int(math.ceil(width / float(pixelation))), int(math.ceil(height / float(pixelation))))) pix = im.load() # random bg colour colours = util.get_dominant_colours(im, 2) colours = map(tuple, colours) colours += [(0,0,0), (255,255,255)] bg_index = random.randint(0, len(colours) - 1) width, height = im.size new = Image.new('RGB', (width * pixelation, height * pixelation), colours[bg_index]) draw = aggdraw.Draw(new) width, height = new.size # draw stitches for y in xrange(0, height, pixelation): for x in xrange(0, width, pixelation): pen = aggdraw.Pen(pix[x / pixelation, y / pixelation], 2) draw.line((x, y, x + pixelation - 3, y + pixelation - 3), pen) draw.line((x + pixelation - 3, y, x, y + pixelation - 3), pen) draw.flush() return new
def stitch(im, pixelation=12): im = im.convert('RGB') im = util.resize_jam_background(im) width, height = im.size # pixelate im = im.resize((int(math.ceil(width / float(pixelation))), int(math.ceil(height / float(pixelation))))) pix = im.load() # random bg colour colours = util.get_dominant_colours(im, 2) colours = map(tuple, colours) colours += [(0, 0, 0), (255, 255, 255)] bg_index = random.randint(0, len(colours) - 1) width, height = im.size new = Image.new('RGB', (width * pixelation, height * pixelation), colours[bg_index]) draw = aggdraw.Draw(new) width, height = new.size # draw stitches for y in xrange(0, height, pixelation): for x in xrange(0, width, pixelation): pen = aggdraw.Pen(pix[x / pixelation, y / pixelation], 2) draw.line((x, y, x + pixelation - 3, y + pixelation - 3), pen) draw.line((x + pixelation - 3, y, x, y + pixelation - 3), pen) draw.flush() return new
def glitch(im, min_pixelation=3, max_pixelation=18, max_attempts=20, min_diff=5000, max_diff=25000, darken=True): try: sh.glitch except sh.CommandNotFound: print 'Could not find glitch. Did you build and install it?' sys.exit(1) im = im.convert('RGB') im = util.resize_jam_background(im) width, height = im.size pixelation = random.random() % (max_pixelation - min_pixelation) + min_pixelation im = im.resize((int(width / pixelation), int(height / pixelation))) im = im.resize((int(width), int(height))) infile = tempfile.NamedTemporaryFile(suffix='.jpg', prefix='glitchtmp', delete=False) outfile = tempfile.NamedTemporaryFile(suffix='.jpg', prefix='glitchtmp', delete=False) infile.close() outfile.close() im.save(infile.name) # naive image diff to ensure image is not too different from original for attempt in range(max_attempts): sh.glitch(infile.name, outfile.name) inim = Image.open(infile.name) outim = Image.open(outfile.name) inpix = inim.resize((10, 10)).load() outpix = outim.resize((10, 10)).load() diff = 0 for y in range(10): for x in range(10): for i in range(3): diff += abs(inpix[x, y][i] - outpix[x, y][i]) if diff > min_diff and diff < max_diff: break im = Image.open(outfile.name) if darken: im = im.point(lambda p: p * .8) os.unlink(infile.name) os.unlink(outfile.name) return im
def halftone(original, radius=3, border=21, black_and_white=False): owidth, oheight = original.size original = util.resize_jam_background(original, owidth + border * 2, oheight + border * 2) original = original.convert('RGB') width, height = original.size if black_and_white: bg = (255, 255, 255) fg = (0, 0, 0) else: colours = util.get_dominant_colours(original, 10) colours = util.order_colours_by_brightness(colours) fg = tuple(random.choice(colours[-6:])) bg = tuple(random.choice(colours[:3])) if fg == bg: bg = (255, 255, 255) fg = (0, 0, 0) original = Contrast(original).enhance(1.5) pix = original.load() new = Image.new('RGB', (width, height), bg) draw = aggdraw.Draw(new) pen = aggdraw.Pen(fg) brush = aggdraw.Brush(fg) x_incr = 2 * radius y_incr = math.sqrt(3) * radius for y in xrange(0, height + 1, int(y_incr)): odd_offset = radius * (y / int(y_incr) % 2) for x in range(odd_offset, width + 1, x_incr): avg_gray = util.get_avg_gray(pix, x, y, radius) if avg_gray > .9: r = radius rnd = lambda: 1 else: r = radius * avg_gray rnd = lambda: 1 + random.randint(-1, 1) / 5.0 draw.ellipse((x - r * rnd(), y - r * rnd(), x + r * rnd(), y + r * rnd()), pen, brush) draw.flush() new = util.centre_crop(new, owidth, oheight) new = new.point(lambda p: p - 20) return new
def glitch(im, min_pixelation=3, max_pixelation=18, max_attempts=20, min_diff=5000, max_diff=25000, darken=True): try: sh.glitch except sh.CommandNotFound: print 'Could not find glitch. Did you build and install it?' sys.exit(1) im = im.convert('RGB') im = util.resize_jam_background(im) width, height = im.size pixelation = random.random() % (max_pixelation - min_pixelation) + min_pixelation im = im.resize((int(width / pixelation), int(height / pixelation))) im = im.resize((int(width), int(height))) infile = tempfile.NamedTemporaryFile(suffix='.jpg', prefix='glitchtmp', delete=False) outfile = tempfile.NamedTemporaryFile(suffix='.jpg', prefix='glitchtmp', delete=False) infile.close() outfile.close() im.save(infile.name) # naive image diff to ensure image is not too different from original for attempt in xrange(max_attempts): sh.glitch(infile.name, outfile.name) inim = Image.open(infile.name) outim = Image.open(outfile.name) inpix = inim.resize((10, 10)).load() outpix = outim.resize((10, 10)).load() diff = 0 for y in xrange(10): for x in xrange(10): for i in xrange(3): diff += abs(inpix[x, y][i] - outpix[x, y][i]) if diff > min_diff and diff < max_diff: break im = Image.open(outfile.name) if darken: im = im.point(lambda p: p * .8) os.unlink(infile.name) os.unlink(outfile.name) return im
def halftone(original, radius=3, border=21, black_and_white=False): original = util.resize_jam_background(original, util.WIDTH + border * 2, util.HEIGHT + border * 2) original = original.convert('RGB') width, height = original.size if black_and_white: bg = (255, 255, 255) fg = (0, 0, 0) else: colours = util.get_dominant_colours(original, 10) colours = util.order_colours_by_brightness(colours) fg = tuple(random.choice(colours[-6:])) bg = tuple(random.choice(colours[:3])) if fg == bg: bg = (255, 255, 255) fg = (0, 0, 0) original = Contrast(original).enhance(1.5) pix = original.load() new = Image.new('RGB', (width, height), bg) draw = aggdraw.Draw(new) pen = aggdraw.Pen(fg) brush = aggdraw.Brush(fg) x_incr = 2 * radius y_incr = math.sqrt(3) * radius for y in xrange(0, height + 1, int(y_incr)): odd_offset = radius * (y / int(y_incr) % 2) for x in range(odd_offset, width + 1, x_incr): avg_gray = util.get_avg_gray(pix, x, y, radius) if avg_gray > .9: r = radius rnd = lambda: 1 else: r = radius * avg_gray rnd = lambda: 1 + random.randint(-1, 1) / 5.0 draw.ellipse( (x - r * rnd(), y - r * rnd(), x + r * rnd(), y + r * rnd()), pen, brush) draw.flush() new = util.centre_crop(new, util.WIDTH, util.HEIGHT) new = new.point(lambda p: p - 20) return new
def blur(original, sigma=10, darken=True): original = util.resize_jam_background(original) original = original.convert('RGB') if darken: original = original.point(lambda p: p * .8) image = np.asarray(original) image = image.transpose((2, 0, 1)) r = ndimage.gaussian_filter(image[0], sigma=sigma) g = ndimage.gaussian_filter(image[1], sigma=sigma) b = ndimage.gaussian_filter(image[2], sigma=sigma) image = np.array([r, g, b]).transpose((1, 2, 0)) return Image.fromarray(image)
def blur(original, sigma=10, darken=True): original = util.resize_jam_background(original) original = original.convert('RGB') if darken: original = original.point(lambda p: p * .8) image = scipy.misc.fromimage(original, flatten=False) image = image.transpose((2, 0, 1)) r = ndimage.gaussian_filter(image[0], sigma=sigma) g = ndimage.gaussian_filter(image[1], sigma=sigma) b = ndimage.gaussian_filter(image[2], sigma=sigma) image = np.array([r, g, b]).transpose((1, 2, 0)) return scipy.misc.toimage(image)
else: crop_bounds = (0, 0, new_w, new_h) return image.crop(crop_bounds) def iter_tiles(image, tile_size): """Yields (x, y) coordinate pairs for the top left corner of each tile in the given image, based on the given tile size. """ w, h = image.size for y in range(0, h, tile_size): for x in range(0, w, tile_size): yield x, y def guess_tile_size(image): """Try to pick an appropriate tile size based on the image's size.""" # Formula: 5% of the largest dimension of the image return int(max(image.size) * 0.05) if __name__ == '__main__': image = Image.open(sys.argv[1]) image = image.convert('RGB') tile_size = 32 width = util.WIDTH + tile_size - (util.WIDTH % tile_size) height = util.HEIGHT + tile_size - (util.HEIGHT % tile_size) image = util.resize_jam_background(image, width, height) image = pxl(image) image.save(sys.argv[2], quality=90)
return image else: crop_bounds = (0, 0, new_w, new_h) return image.crop(crop_bounds) def iter_tiles(image, tile_size): """Yields (x, y) coordinate pairs for the top left corner of each tile in the given image, based on the given tile size. """ w, h = image.size for y in xrange(0, h, tile_size): for x in xrange(0, w, tile_size): yield x, y def guess_tile_size(image): """Try to pick an appropriate tile size based on the image's size.""" # Formula: 5% of the largest dimension of the image return int(max(image.size) * 0.05) if __name__ == '__main__': image = Image.open(sys.argv[1]) image = image.convert('RGB') tile_size = 32 width = util.WIDTH + tile_size - (util.WIDTH % tile_size) height = util.HEIGHT + tile_size- (util.HEIGHT % tile_size) image = util.resize_jam_background(image, width, height) image = pxl(image) image.save(sys.argv[2], quality=90)