이번에 아이폰을 새로 장만하면서 사진을 찍고 블로그에 올리다가 문제를 발견했다.
이전 아이폰 12 mini에서는 내가 설정을 해놨었는지, 문제가 없었는데...
이미지 포맷이 heic(High Efficiency Image Container)라는 포맷으로 기본 사진이 촬영된다...!
고화질을 유지하면서 용량이 작은 IOS에서 많이 사용되는 이미지 파일 형식이라는데...
이게 문제가 뭐냐면 우리 집의 개인 PC는 Windows 11 Pro가 설치되어 있는데, 코덱이 없어서 이미지가 안 열린다.
뭐 쉽게 프로그램 하나 만들어서 변환하면 되겠지 했는데, 이게 생각보다 만만하지 않았다.
1. 이미지 변환 코덱
HEIC 포맷은 라이선스가 있는 HEVC 코덱을 사용한다. 따라서 일반적인 오픈소스에는 위의 코덱이 포함되지 않는다.
대신 대부분의 라이브러리가 C++로 작성된 libheif라는 네이티브 라이브러리를 호출하는 방식으로 동작한다.
libheif 라이브러리는 리눅스 계열에서는 간단하게 설치할 수 있지만, 윈도 계열에서는 다운로드하여서 직접 빌드해야 한다.
문제는 내 개발 pc가 윈도고, 나는 c++ 컴파일러를 pc에 설치하고 싶진 않다. 안 그래도 적은 용량......
2. 도커 컨테이너 사용
대신 도커에 우분투를 베이스이미지로 설치하고, 그 위에 필요한 코덱을 다운로드해서 cli로 동작하는 컨테이너를 만들어야겠다고 생각했다.
- 우분투 > libheif > NodeJS > js파일 실행
1. package.json
{
"name": "heic-converter",
"version": "1.0.0",
"description": "HEIC to JPG converter on Docker",
"main": "convert.js",
"scripts": {
"start": "node convert.js"
},
"dependencies": {
"heic-convert": "^1.2.4"
}
}
2. convert.js
nodejs와 heic-convert를 사용해서 컨테이너에 포함된 libheif 라이브러리를 호출할 생각이다.
cli로 실행할 거니까, input / output 폴더만 파라미터로 제공하자.
input / output은 도커로 cli 명령을 실행할 때, 볼륨으로 연결해 줄 예정이다.
const fs = require('fs').promises;
const path = require('path');
const convert = require('heic-convert');
const inputDir = './input';
const outputDir = './output';
(async () => {
try {
// input/output 디렉터리가 없으면 생성
await fs.mkdir(inputDir, { recursive: true });
await fs.mkdir(outputDir, { recursive: true });
const files = await fs.readdir(inputDir);
const heicFiles = files.filter(file => file.toLowerCase().endsWith('.heic'));
if (heicFiles.length === 0) {
console.log(`'${inputDir}' 디렉터리에서 HEIC 파일을 찾을 수 없습니다.`);
return;
}
console.log(`${heicFiles.length}개의 HEIC 파일 변환을 시작합니다.`);
for (const heicFile of heicFiles) {
const inputPath = path.join(inputDir, heicFile);
const outputPath = path.join(outputDir, `${path.parse(heicFile).name}.jpg`);
try {
process.stdout.write(`'${inputPath}' 변환 중... `);
const inputBuffer = await fs.readFile(inputPath);
const outputBuffer = await convert({
buffer: inputBuffer,
format: 'JPEG',
quality: 0.9
});
await fs.writeFile(outputPath, outputBuffer);
console.log(`✅ -> '${outputPath}' 에 저장 완료`);
} catch (fileError) {
console.log(`❌ -> 변환 실패: ${fileError.message}`);
}
}
} catch (error) {
console.error('전체 작업 중 오류가 발생했습니다:', error);
}
})();
3. dockerfile
도커 베이스 이미지는 우분투를 사용한다.
필요한 패키지들을 설치해야 한다.
nodejs 설치를 위한 curl, gnupg, ca-certificates
libheif 라이브러리를 포함하는 libheif-examples
# 1. 베이스 이미지 선택 (Ubuntu 22.04 LTS)
FROM ubuntu:22.04
# Docker 빌드 중 대화형 프롬프트 방지
ENV DEBIAN_FRONTEND=noninteractive
# 2. 시스템 패키지 및 Node.js 설치
# 모든 설치 과정을 하나의 RUN 명령으로 통합하여 안정성 확보
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
gnupg \
libheif-examples && \
# NodeSource 저장소 추가 및 Node.js 설치
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y --no-install-recommends nodejs && \
# 설치 후 불필요한 apt 캐시 정리
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 3. 애플리케이션 코드 준비 (이전과 동일)
WORKDIR /usr/src/app
COPY package*.json ./
# npm 의존성 설치
RUN npm install
# 나머지 소스 코드 전체 복사
COPY . .
# 4. 컨테이너 실행 시 실행될 기본 명령어
CMD [ "node", "convert.js" ]
위의 도커파일을 빌드해서
docker build -t heic-converter .
다음과 같이 사용하면 된다.
docker run --rm \
-v [파일들이 들어있는 경로]:/usr/src/app/input \
-v [output을 원하는 경로]:/usr/src/app/output \
heic-converter
실행!
도커의 자원 사용량
1) input 폴더
2) output 폴더
짠!
이래서 도커 쓰지...!
'공부' 카테고리의 다른 글
[매크로] 게임 매크로 만들어보기 (0) | 2025.06.20 |
---|---|
[CI/CD] Gitea + Act_Runner (1) | 2025.06.13 |
[GCP] Nginx SSL 자동갱신 (1) | 2025.06.13 |
[REST] API 요청, 응답 (2) | 2025.06.12 |
[BE] SSE 재연결과 관련된 시간 (0) | 2025.06.12 |