alpha composits and transposing big image
This commit is contained in:
parent
7a6d92b39b
commit
8d744f686a
62
mosiac.py
62
mosiac.py
|
@ -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__":
|
||||||
|
|
Loading…
Reference in New Issue
Block a user