alpha composits and transposing big image

This commit is contained in:
iou1name 2017-12-16 13:55:35 -05:00
parent 7a6d92b39b
commit 8d744f686a

View File

@ -29,7 +29,7 @@ class Mosiac():
self.matrixSize = None self.matrixSize = None
def openBigImage(self, imagePath, mat=(20,40)): def openBigImage(self, imagePath, mat=(40,20)):
""" """
Opens and initializes the big image. Opens and initializes the big image.
""" """
@ -77,7 +77,7 @@ class Mosiac():
if image.mode == "P": if image.mode == "P":
image = image.convert(image.palette.mode) image = image.convert(image.palette.mode)
if image.mode == "RGBA": if image.mode == "RGBA":
image = alpha_composite_with_color(image).convert("RGB") image = alpha_composite(image).convert("RGB")
if image.mode == "L": if image.mode == "L":
image = image.convert("RGB") image = image.convert("RGB")
# image = image.convert("RGBA") # image = image.convert("RGBA")
@ -117,6 +117,8 @@ class Mosiac():
cluster = {pixel: self.imageBank[pixel] for pixel in \ cluster = {pixel: self.imageBank[pixel] for pixel in \
sort[n*num:n*num+num]} sort[n*num:n*num+num]}
self.clusters.append(cluster) self.clusters.append(cluster)
# shove the left overs into the last cluster
self.clusters[-1].update({pixel: self.imageBank[pixel] for pixel in \ self.clusters[-1].update({pixel: self.imageBank[pixel] for pixel in \
sort[-(len(sort) % num):]}) sort[-(len(sort) % num):]})
@ -143,7 +145,7 @@ class Mosiac():
tol = int(len(dist) * self.tolerance) tol = int(len(dist) * self.tolerance)
tol += int(tol == 0) tol += int(tol == 0)
indexs = dist.argsort()[:tol] indexs = dist.argsort()[:tol]
# choice = dist.argmin() # closet value # choice = indexs.argmin() # closet value
choice = np.random.choice(indexs) choice = np.random.choice(indexs)
return cluster[tuple(nodes[choice])] return cluster[tuple(nodes[choice])]
@ -156,6 +158,9 @@ class Mosiac():
pixels = list(self.smallImage.getdata()) pixels = list(self.smallImage.getdata())
for pixel in pixels: for pixel in pixels:
image = self.nearestImage(pixel) image = self.nearestImage(pixel)
image = image.convert("RGBA")
comp = Image.new("RGBA", image.size, pixel + (30,))
image = Image.alpha_composite(image, comp).convert("RGB")
self.imageMatrix.append(image) self.imageMatrix.append(image)
print(f"buildMatrix took: {time.time()-then} seconds.") print(f"buildMatrix took: {time.time()-then} seconds.")
@ -166,12 +171,16 @@ class Mosiac():
""" """
then = time.time() then = time.time()
image = Image.new("RGB", self.bigImageSize, (255,255,255)) image = Image.new("RGB", self.bigImageSize, (255,255,255))
# self.bigImage = self.bigImage.crop((0,0,self.bigImageSize[0],self.bigImageSize[1])) self.bigImage = self.bigImage.crop(
(0, 0, self.bigImageSize[0], self.bigImageSize[1]))
n = 0 n = 0
for y in range(0, self.bigImageSize[1], self.tileSize[1]): for y in range(0, self.bigImageSize[1], self.tileSize[1]):
for x in range(0, self.bigImageSize[0], self.tileSize[0]): for x in range(0, self.bigImageSize[0], self.tileSize[0]):
image.paste(self.imageMatrix[n], box=(x,y)) image.paste(self.imageMatrix[n], box=(x,y))
n += 1 n += 1
image = image.convert("RGBA")
self.bigImage.putalpha(50)
image = Image.alpha_composite(image, self.bigImage).convert("RGB")
# self.bigImage.save(os.path.join(root, "mosiac.png"), "PNG") # self.bigImage.save(os.path.join(root, "mosiac.png"), "PNG")
image.save(os.path.join(root, "mosiac.jpg"), "JPEG", optimize=True, quality=90) image.save(os.path.join(root, "mosiac.jpg"), "JPEG", optimize=True, quality=90)
print(f"buildMosiac took: {time.time()-then} seconds.") print(f"buildMosiac took: {time.time()-then} seconds.")
@ -189,46 +198,15 @@ def step (r,g,b, repetitions=1):
return (h2, lum, v2) return (h2, lum, v2)
def alpha_composite(front, back): def alpha_composite(image, color=(255, 255, 255)):
"""Alpha composite two RGBA images. """
Alpha composite an RGBA Image with a specified color.
Source: http://stackoverflow.com/a/9166671/284318 Source: http://stackoverflow.com/a/9166671/284318
Keyword Arguments:
front -- PIL RGBA Image object
back -- PIL RGBA Image object
""" """
front = np.asarray(front) image.load() # needed for split()
back = np.asarray(back) background = Image.new('RGB', image.size, color)
result = np.empty(front.shape, dtype='float') background.paste(image, mask=image.split()[3]) # 3 is the alpha channel
alpha = np.index_exp[:, :, 3:] return background
rgb = np.index_exp[:, :, :3]
falpha = front[alpha] / 255.0
balpha = back[alpha] / 255.0
result[alpha] = falpha + balpha * (1 - falpha)
old_setting = np.seterr(invalid='ignore')
result[rgb] = (front[rgb] * falpha + back[rgb] * balpha * (1 - falpha)) / result[alpha]
np.seterr(**old_setting)
result[alpha] *= 255
np.clip(result, 0, 255)
# astype('uint8') maps np.nan and np.inf to 0
result = result.astype('uint8')
result = Image.fromarray(result, 'RGBA')
return result
def alpha_composite_with_color(image, color=(255, 255, 255)):
"""Alpha composite an RGBA image with a single color image of the
specified color and the same size as the original image.
Keyword Arguments:
image -- PIL RGBA Image object
color -- Tuple r, g, b (default 255, 255, 255)
"""
back = Image.new('RGBA', size=image.size, color=color + (255,))
return alpha_composite(image, back)
if __name__ == "__main__": if __name__ == "__main__":