Created
May 5, 2024 07:49
-
-
Save damp11113/00bea1baba91f5c4cbb9b16c3d75a5f8 to your computer and use it in GitHub Desktop.
camouflage generator using cellular automata algorithm v2. add smooth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import numpy as np | |
from PIL import Image, ImageDraw, ImageFilter | |
from damp11113.processbar import indeterminateStatus | |
class camogen: | |
def __init__(self, grid_size=128, num_frames=15, color=[(75, 83, 32), (225, 215, 152), (103, 86, 69), (66, 71, 86)], ranseedx=0, ranseedy=100, blur=3, index=5): | |
self.grid_size = (grid_size, grid_size) | |
self.num_frames = num_frames | |
self.colors = color | |
self.ranseedx = ranseedx | |
self.ranseedy = ranseedy | |
self.blur = blur | |
self.index = index | |
def initialize_grid(self, seed=None): | |
if seed is not None: | |
np.random.seed(seed) | |
return np.random.choice([0, 1], size=self.grid_size) | |
def apply_rules(self, grid): | |
neighbor_count = sum(np.roll(np.roll(grid, i, 0), j, 1) for i in (-1, 0, 1) for j in (-1, 0, 1) if (i != 0 or j != 0)) | |
return (neighbor_count == 3) | (grid & (neighbor_count == 2)) | |
def update_grid(self, grid): | |
new_grid = self.apply_rules(grid) | |
grid[:] = new_grid[:] | |
return grid | |
def generate_frames(self, grid): | |
images = [] | |
for idx in range(self.num_frames): | |
img = Image.new('RGBA', self.grid_size) | |
draw = ImageDraw.Draw(img) | |
for i in range(self.grid_size[0]): | |
for j in range(self.grid_size[1]): | |
if grid[i, j] == 1: | |
draw.rectangle([j, i, j + 1, i + 1], fill='black') | |
img = img.convert("RGBA") | |
datas = img.getdata() | |
newData = [] | |
for item in datas: | |
if item[0] in range(200, 256) and item[1] in range(200, 256) and item[2] in range(200, 256): | |
newData.append((255, 255, 255, 0)) | |
else: | |
newData.append(item) | |
img.putdata(newData) | |
images.append(img) | |
grid = self.update_grid(grid) | |
return images | |
def gen(self): | |
loading = indeterminateStatus(desc=f"generating camo {self.grid_size[0]}x{self.grid_size[1]}", end="[ ✔ ] generated") | |
loading.start() | |
# Randomly choose a new position for each color | |
new_positions = list(range(len(self.colors))) | |
random.shuffle(new_positions) | |
# Create a new list with colors shuffled to new positions | |
colors = [self.colors[i] for i in new_positions] | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 0" | |
L0 = Image.new("RGBA", self.grid_size) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 1" | |
TL1 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index] | |
thresed = TL1.point(lambda p: p > 128 and 255) | |
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur)) | |
L1 = blured.point(lambda p: p > 128 and 255) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 2" | |
TL2 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index] | |
thresed = TL2.point(lambda p: p > 128 and 255) | |
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur)) | |
L2 = blured.point(lambda p: p > 128 and 255) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} layer 3" | |
TL3 = self.generate_frames(self.initialize_grid(random.randint(self.ranseedx, self.ranseedy)))[self.index] | |
thresed = TL3.point(lambda p: p > 128 and 255) | |
blured = thresed.filter(ImageFilter.GaussianBlur(self.blur)) | |
L3 = blured.point(lambda p: p > 128 and 255) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 0" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B = colors[0] | |
L0.putpixel((x, y), (R, G, B, 255)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 1" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L1.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[1] | |
L1.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 2" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L2.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[2] | |
L2.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} painting layer 3" | |
for x in range(self.grid_size[0]): | |
for y in range(self.grid_size[1]): | |
R, G, B, A = L3.getpixel((x, y)) | |
if A == 255: | |
R, G, B = colors[3] | |
L3.putpixel((x, y), (R, G, B, A)) | |
loading.desc = f"generating camo {self.grid_size[0]}x{self.grid_size[1]} mixing" | |
merged_image = Image.alpha_composite(L0, L1) | |
merged_image = Image.alpha_composite(merged_image, L2) | |
merged_image = Image.alpha_composite(merged_image, L3) | |
loading.stop() | |
return merged_image | |
for i in range(10): | |
camo = camogen(512, index=20, num_frames=30) | |
outcamo = camo.gen() | |
outcamo.save(f"./camo/v2/{i}.png") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
output
