반응형
17+ 개의 PNG 레이어들을 랜덤으로 병합하여 10,000개의 이미지를 만들어내는 프로젝트를 진행중이다. 처음 single-thread 방식으로 구현하였을때 6시간이 걸리길래 식겁한 경험이 있다.
이를 단 20분으로 줄인 방법을 설명하고자 한다.
다음은 Pillow 라이브러리를 이용해 이미지 레이어를 합성하는 예시이다.
def merge_image_layer(self, trait):
image_layer_path = self.parse_image_directory(trait) # layer PNG image directories
stack = Image.new('RGBA', (self.width, self.height)) # create new image canvas
for layer, path in image_layer_path.items():
image_layer = Image.open(path).convert('RGBA')
stack = Image.alpha_composite(stack, image_layer) # merge
stack = stack.convert('RGB') # remove alpha to compress
stack.save(f'./images/{trait["token_id"]}.jpeg') # save as jpeg
이를 10,000번 혹은 그 이상을 반복한다면 당연히 시간복잡도는 기하급수적으로 늘어날것이다.
현재 개발기기로는 M1 pro를 사용중에 있는데 무려 CPU가 10개나 된다. 백번 활용해보자.
아래와 같이 파이썬에 내장된 multiprocessing 라이브러리를 활용
해 구현하였다.
tqdm은 progress bar를 콘솔창에 표시하는 라이브러리 이다.
print(f"multi threading with {multiprocessing.cpu_count()} CPUs")
pool = Pool(processes=multiprocessing.cpu_count())
for _ in tqdm.tqdm(pool.imap_unordered(self.merge_image_layer, traits), total=len(traits), unit=" image"):
pass
pool.close()
pool.join()
pillow를 통한 in-memory 이미지 합성의 속도는 향상시킬수 있어도 생각했던 것처럼 이미지 IO Thread Lock으로 인해서 어어엄청 빨라지지는 않는다. 그래도 6시간 걸리던거 20분이면 만족한다..
반응형
'Python' 카테고리의 다른 글
리스트에서 랜덤으로 원소 뽑기 - python list random choices (0) | 2022.05.26 |
---|