2020년 1월 10일 금요일

리눅스에서 여러 개의 이미지 파일을 하나로 합치기

2020년에 접어든 이후 겨우 5일에 한번 정도의 글을 쓰고 있다. 매우 바쁘거나, 또는 마음에 여유가 없다는 뜻이 되겠다. 업무와 집안일에 파묻혀서 이렇게 건조한 나날을 보내서는 안되겠다.

수십 개의 시퀀싱 라이브러리에 대한 QC 관련 이미지 파일을 하나로 병합하고 싶다. 어떻게 하면 좋을까? 정답은 바로 ImageMagick이 갖고 있었다. 파워포인트에서 이미지 파일들을 늘어놓고 간격을 맞춘 다음 이를 묶어서 export하는 대단히 미련하고도 끔찍한 방법은 이제 버리도록 하자. ImageMagick의 강력한 기능을 이제 알게 되다니 그동안 겪은 어리석은 경험이 너무나 안타깝다.

$ convert +append image1.png image2.png out.png # 가로로 붙이기
$ convert -append image1.png image2.png out.png # 세로로 붙이기
$ convert +append -geometry 240x a.png b.png output.png # 크기 변환

이 방법으로는 이미지를 가로나 세로 한 줄로만 배열할 수 있다. 만약 타일 형태로 늘어놓고 싶다면? montage 명령을 쓰면 된다.

$ montage -mode concatenate -tile 3x8 *png output.png

-mode와 -tile 옵션을 주지 않으면 최종 이미지의 크기와 가로 및 세로로 늘어놓을 이미지의 수를 알아서 결정한다.

이것으로도 상당히 일손을 덜 수 있다. 그런데 처리할 원본 이미지는 LMT1-2.png, LMT1-10.png, LMT12-2.png와 같은 형태의 이름을 갖고 있다. 이를 *png 형태로 montage 명령의 인수로 공급하면 원하는 순서대로 정렬이 되지 않는다. sort -V 명령을 쓰면 이를 해결할 수 있다.

$ sort list 
LMT13-37
LMT15-1
LMT15-24
LMT15-4
LMT15-6
LMT16-16
LMT17-25
LMT17-31
LMT17-36
LMT17-40
LMT17-43
LMT17-62
LMT17-74
LMT17-75
LMT19-13
LMT19-27
LMT19-3
LMT19-32
LMT19-36
LMT19-37
LMT19-6
LMT2-17
LMT2-3
LMT7-21
$ sort -V list
LMT2-3
LMT2-17
LMT7-21
LMT13-37
LMT15-1
LMT15-4
LMT15-6
LMT15-24
LMT16-16
LMT17-25
LMT17-31
LMT17-36
LMT17-40
LMT17-43
LMT17-62
LMT17-74
LMT17-75
LMT19-3
LMT19-6
LMT19-13
LMT19-27
LMT19-32
LMT19-36
LMT19-37

힌트는 How do I sort mixed text & numbers (eg hostnames)?에서 얻었다. 기본 가정은 GNU coreutils ≥ 7.0이어야 한다는 점이다.

그러면 현 디렉토리에 있는 모든 png 파일을 이러한 방식으로 정렬한 다음, 이를 ImageMagick montage 명령어에 인수로 공급하려면 어떻게 하면 좋을까? 바로 작년 10월에 포스팅했었던 process substitution을 응용하면 된다.

$ montage -mode concatenate -tile 3x8 `sort -V <(ls *png)` output.png

난해한 것 같으나 대단히 아름답고도 간결하다. ls *png의 결과물을 sort -V에 공급하고, 그 출력물이 montage 명령어의 인수로 제공된다. `sort -V <(ls *png)`라 쓰지 않고 대신 <(sort -V <(ls *png))라고 해도 되지 않을까 생각했었지만 테스트를 해 보니 중첩해서 쓸 수는 없었다.

구글에서 'imagemagick covert 사용법'으로 검색을 하면 오래전인 2008년 12월 31일에 작성된 [개발자팁] 이미지매직(ImageMagick) 명령어 예제 및 설명이 나온다. 그만큼 많은 사람들이 이 글을 참조했었다는 이야기가 된다.

댓글 없음: