Skip to content

Instantly share code, notes, and snippets.

@Adjective-Object
Last active March 29, 2017 19:20
Show Gist options
  • Save Adjective-Object/8764ff1fc2839de0bd286d20ab89cb8a to your computer and use it in GitHub Desktop.
Save Adjective-Object/8764ff1fc2839de0bd286d20ab89cb8a to your computer and use it in GitHub Desktop.
insert transparent images into other images
from PIL import Image, ImageCms
import numpy as np
import matplotlib.pyplot as plt
import pylab
from scipy import signal, ndimage
import scipy
import os
import random
##############
# transforms #
##############
srgb_profile = ImageCms.createProfile("sRGB")
lab_profile = ImageCms.createProfile("LAB")
rgb2lab_transform = ImageCms.buildTransformFromOpenProfiles(
srgb_profile, lab_profile, "RGB", "LAB")
##############
# transforms #
##############
def center_spectrum(im):
h, w = im.shape[0], im.shape[1]
q1 = im[h/2:, :w/2]
q2 = im[h/2:, w/2:]
q3 = im[:h/2, :w/2]
q4 = im[:h/2, w/2:]
upper_half = pylab.hstack((q2, q1))
lower_half = pylab.hstack((q4, q3))
im = pylab.vstack((upper_half, lower_half))
return im
def scale(arr, factor):
return scipy.misc.imresize(
arr,
(int(arr.shape[0] / factor), int(arr.shape[1]/ factor)),
interp="bilinear") / 255.0
scale_factor = 8
pad=4
def overlay_image_coords(target, overlay):
target_arr = np.average(np.array(target), axis=2) / 255.0
overlay_arr = np.array(overlay)[:,:,3] / 255.0
print "edge detection"
blur_arr = ndimage.filters.gaussian_filter(target_arr, 2)
edges = blur_arr - target_arr
edges = - edges
edges -= edges.min()
edges = edges / edges.max()
print edges.max(), edges.min(), "<<"
# plt.imshow(edges)
# plt.show()
print "convolving edges with gaussian to provide border"
edges = edges - np.average(edges)
edges_gauss = ndimage.filters.gaussian_filter(edges, 20)
edges = np.maximum(edges, edges_gauss)
# plt.imshow(edges)
# plt.show()
print "convolving with overlay.."
edges = scale(edges, scale_factor)
overlay_arr = scale(overlay_arr, scale_factor)
unpadded_shape = overlay_arr.shape
overlay_arr = np.pad(overlay_arr, [[pad, pad], [pad, pad]], 'constant', constant_values=0)
print "lowres edges:", edges.shape
print "lowres overlay:", overlay_arr.shape
# plt.imshow(edges)
# plt.show()
print "convolving overlay with gaussian to provide border"
overlay_gauss = ndimage.filters.gaussian_filter(overlay_arr, 5)
overlay_arr = np.maximum(overlay_arr, overlay_gauss)
# plt.imshow(overlay_arr)
# plt.show()
print "convolving overlay with edge image"
overlaps = signal.convolve2d(edges, overlay_arr, boundary="fill", fillvalue=np.min(edges))
print "edges:", edges.shape
print "overlay:", overlay_arr.shape
print "image:", target.size
print "overlaps:", overlaps.shape
print "overlaps:", overlaps.shape[0] * scale_factor, overlaps.shape[1] * scale_factor
# plt.imshow(overlaps)
# plt.show()
print "cropping"
# prevent anime grills from being placed out of image
overlaps = overlaps[
int(overlay_arr.shape[0] * 1) : int(-overlay_arr.shape[0] * 1),
int(overlay_arr.shape[1] * 1) : int(-overlay_arr.shape[1] * 1),
]
print "overlaps:", overlaps.shape
print "overlaps:", overlaps.shape[0] * scale_factor, overlaps.shape[1] * scale_factor
# plt.imshow(overlaps)
# plt.show()
flat_index = np.argmin(overlaps)
coords = np.unravel_index(flat_index, overlaps.shape)
cx = int(float(coords[1] + overlay_arr.shape[1]/2 + pad) / edges.shape[1] * target.size[0])
cy = int(float(coords[0] + overlay_arr.shape[0]/2 + pad) / edges.shape[0] * target.size[1])
overlay_arr = scale(overlay_arr, 1.0/scale_factor)
overlay_arr = np.repeat(
np.reshape(overlay_arr, (overlay_arr.shape[0], overlay_arr.shape[1], 1)),
3,
axis=2)
x = (overlay_arr * 255).astype(np.uint8)
print x.shape, x.dtype
img = Image.fromarray(x)
return (cx, cy), img
assetpath = os.path.join(
os.getcwd(),
"smug"
)
imgs = [
os.path.join(assetpath, p)
for p in os.listdir(assetpath)
]
def maybe_resize(screenshot, smug):
ratio = max(
(smug.size[0] + pad * scale_factor * 2.0) / screenshot.size[0],
(smug.size[1] + pad * scale_factor * 2.0) / screenshot.size[1],
)
if (ratio > 0.5):
print "downscaling smugness to fit on page", screenshot.size
newsize = (
0.5 / ratio *smug.size[0],
0.5 / ratio *smug.size[1]
)
smug.thumbnail(newsize, Image.ANTIALIAS)
print "resulting smugness is ", smug.size
return smug
def main():
screenshot = Image.open("screenshot.png")
smugpath = random.choice(imgs)
print smugpath
smug = Image.open(smugpath)
# ensure overlay smaller than image
smug = maybe_resize(screenshot, smug)
coords, img = overlay_image_coords(screenshot, smug)
print "found coords", coords
# screenshot.paste(img, (coords[0] - pad * scale_factor, coords[1] - pad * scale_factor))
coords = (
coords[0] - img.size[0] / 2,
coords[1] - img.size[1] / 2
)
screenshot.paste(smug, coords, smug)
print "writing out.png"
screenshot.save("out.png")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment