본문 바로가기

Programming/Python Program

[PYTHON] 간단히 이미지(사진)들 합치기 by using python - Merge images by using python program.

안녕하세요. 이번에는 여러장의 이미지(사진)들을 하나의 파일로 병합(합치기)하는 과정을 파이썬을 이용해서 코딩해 보겠습니다.

주로 이미지를 다룰때는 이미지 관련 툴(가령 포토샵)들을 많이 사용을 합니다. 그러나 이런 툴들을 다루더라도 여러장의 파일들을 열고 사이즈에 맞게 붙이고 크기 조절하고 저장하고 일련의 과정들을 거쳐야합니다. 다소 번거로울 수도 있는 이런 일들을 프로그램으로 간단히 처리하게 하려고 합니다. 물론 디테일한 프로세싱은 상기의 툴을 이용하는게 나을수도 있습니다. 그래서 여기서는 단순하게 몇장의 이미지들을 같은 규격의 사이즈로 크기 조절 후 가로형태로 나란히 붙여주게끔만 하겠습니다. 이를 잘 숙지하고 응용을 한다면, 여느 프로그램 못지않은 나만의 툴을 구현할 수 있을 것입니다. 각설하고 시작하겠습니다.



시작하기



우선 이미지를 다룰 예정이므로, 관련 모듈인 'pillow'모듈을 불러옵니다. 그리고 파일을 찾아서 처리하기에 glob 도 불러옵니다.

이미지 파일들이 있는 대상 폴더를 지정합니다.

glob을 이용하여 대상 폴더에 있는 모든 파일들(혹은 이미지 파일들 *.jpg , *.png, *.bmp, *.jpeg ....etc.)들 찾아서 files라는 변수에 넣어줍니다.

현재 대상 폴더에는 아래와 같이 임의의 3개 이미지 파일들이 존재하고 있습니다.

확인을 위해 프린트를 해 보았습니다. 3개의 파일이 있다고 알려주네요.

그리고 각각의 이미지 파일들의 크기(가로,세로)를 찾아 계산할 함수를 정의해 줍니다.

가로, 세로에 해당하는 값들을 담을 리스트를 정의해 줍니다.

반복문을 이용하여 각각의 파일들을 불러들여, 가로값은 size_x에 세로값은 size_y 변수에 저장을 합니다. 

각각의 가로, 세로 값이 잘 저장되어 있는지 확인을 위해 프린트를 사용하였고, 가장 아래에 이 함수를 호출하였습니다.

세 개의 이미지 파일의 가로값인 240, 240, 528  세로값인 251, 286, 192 가 잘 들어갔습니다.

위와 같이 서로 크기가 다른 이미지를 하나의 이미지로 합치려고 하면 크기가 다르기 때문에 합쳐진 이후의 이미지는 공백이 존재하게 되어 미관상 별로 좋지 않을 것입니다. 그래서 이를 방지하고자, 이미지 크기중 가장 작은 값으로 크기를 조절하고 병합을 할 것입니다.  만약 가장 큰 값으로 리사이즈하면 픽셀이 너무 뭉개지게 되어 이 또한 보기 좋지 않기에 가장 픽셀값이 작은 값으로 조절하려고 합니다.


그래서 가로 크기중 가장 작은 값, 세로 크기중 가장 작은 값을 각각의 변수 x_min, y_min 에 저장을 하였습니다. 그리고 서로 다른 이미지를 붙일 것이기에 가로로는 크기를 파일 갯수만큼 조절해 주어야 합니다. 그래서 파일 갯수인 len(files) 에 가로 최소값을 곱해서 가로 방향의 최종값을 구해 주었습니다.▼

각각의 값을 확인하기 위해 프린트로 알아보겠습니다.

가로 최솟값인 240, 세로 최솟값인 192, 가로 최솟값에 파일의 갯수를 곱한 값인 720. 잘 저장이 되었습니다.

각각의 프린트문을 주석처리하고, 사이즈 계산함수의 결과를 리턴해 주었습니다.

이렇게 리턴된 값을 재사용하기 위해 x_min, y_min, x_size에 저장을 합니다.

리턴받은 값들을 이용해 이번에는 리사이즈를 하려고 합니다. 이를 위한 함수 resizeTomin()을 호출하게 합니다. 

리사이즈 함수를 호출하였으니, 이 호출에 응할 함수를 만들어 주어야겠죠? 그래서 이 함수를 아래와 같이 정의해 줍니다.

파일 목록을 담을 리스트를 만들어 줍니다.

각각의 이미지 파일들을 열어서 앞의 함수에서 구한 최솟값들을 이용하여 크기를 조절하겠습니다. 앞서 구한값은 240, 192 였습니다. 그리고 이렇게 크기 조절이 된 이미지들을 위에서 정의한 file_list 에 넣어줍니다. 

각각의 이미지 파일들의 크기를 확인해 보고, 각 이미지들을  보여주게 합니다.

각 이미지들을 아래와 같습니다. 크기는 모두 동일하게 240 * 192로 변환이 되었습니다. 자세히 보면 파일의 이름이 낯설게 명명이 되어 있는데, 이는 프로그램에서 임의의 값을 만들어 주었기 때문입니다.



그리고 각각의 크기는 아래의 결과창에서 확인할 수 있습니다.

결과를 확인했으니 프린트문을 주석처리 하고 리턴값을 설정해 주겠습니다.

앞서 호출한 리사이즈 함수의 리턴값을 file_list, x_size, x_min, y_min 의 변수들이 반환받게 하였습니다.

이제 이렇게 반환받은 값들을 가지고 이번에는 마지막으로 이미지 병합(합치기)를 할 예정입니다. 그러기 위해 병합할 함수를 아래와 같이 호출하게 하였습니다.

함수를 호출하게 하였으니, 해당 함수를 만들어야겠죠? 아래와 같이 함수를 정의하겠습니다. 

우리가 그림을 그릴 때에도 하얀 스케치북에 그림을 그리지 않습니까? 그래서 그런 역활을 할 하얀색 배경( RGB 로 256,256,256) 도화지를 만들어 줍니다. 그 크기는 가로 세로 각각 x_size, y_min 으로 만들게합니다. 이렇게 만든 하얀색 도화지를 new_image 라고 하는 변수에 담겠습니다.

x_size와 파일의 갯수를 확인해 보겠습니다.

도화지의 가로 길이는 앞의 다른 함수에서 구한 가로 최솟값인 240 의 3배입니다. 3은 파일의 갯수가 3개이기 때문입니다. 만약 파일 100개를 해당 폴더에 넣어두면 이 값은 100으로 곱한 값이 될 것입니다.

프린트문을 주석(comment) 처리하고 또 다른 반복문을 사용하겠습니다. 이는 전달받은 file_list의 인덱스값을 활용하려고 합니다.

시작점 가로, 시작점 세로, 이미지의 가로 크기, 이미지의 세로 크기   - > 이렇게 4개의 값을 가지는 area라는 변수를 정의 해 주었습니다. 이는 이미지를 병합해 줄 때 서로 다른 이미지를 겹쳐주게 할 위치값이 됩니다. 주의해야 할 점은 프로그래밍적으로 구현하는 것이기에 각각의 값을 정확하게 하지 않으면 오류가 나기 쉽습니다.  위에서 만든 하얀색 배경 도화지인 new_image에 file_list[index] 에 있는 이미지를 area 범위에 맞게 합쳐라~~~~~~ 라는 의미입니다.

이제 이렇게 병합한 이미지를 확인해 보겠다고 show() 를 넣어주었습니다.

아래와 같이 서로 다른 이미지를 병합하게 하였습니다.

이렇게 만든 이미지를 파일로 저장을 하려고 합니다. 그래서 아래와 같은 코드를 넣어주었습니다. 바탕화면에 result.png 라는 이미지 파일을 뱉어내게 하였습니다.

그랬더니 정말로(-_-) 바탕화면에 위의 이미지를 뱉어 냈습니다.



확인해 보나 마나 앞서 확인한 이미지 입니다.


맺음말.


여기까지가 서로 다른 크기의 이미지를 파이썬을 이용해 병합하는 과정을 알아 보았습니다.

만약 MAC 을 사용하고 계시다면, 보다 높은 생산성을 향상을 위해 병합할 이미지들을 넣을 폴더에 폴더 액션을 걸어두면,

몇장의 이미지를 해당 폴더에 떨구기만 하면, 바탕화면에 병합된 이미지를 뱉어내게 만들어 유용하게 사용할 수 있을 것입니다.

마치 요술 항아리처럼 이미지 몇 장을 넣으니 큰놈(?)으로 하나를 뱉어내게 말이죠...ㅎㅎ;;

수고하셨습니다.