Express.js 서버로 업로드 한 이미지 파일의 배경색을 제거하기
웹 서비스를 운영하다보면 사용자의 도장을 인식하거나, 간단한 사진 합성을 하는 등
사용자가 업로드 한 이미지의 배경색을 제거하고, 이미지의 내용 부분만 추출해야 할 수도 있습니다.
사용자가 이미지를 업로드하면, 배경을 제거하는 예제를 공유합니다.
사전 준비
1. GraphicsMagick을 설치합니다.
- GraphicsMagick은 널리 이용되는 이미지 처리 라이브러리입니다. 이 예제에서는 GraphicsMagick을 이용해 이미지를 처리합니다.
- Windows: 아래 링크에서 다운로드 후 설치를 진행하세요.
http://www.graphicsmagick.org/README.html#installation
- *nix: 아래 링크에서 다운로드 후 설치를 진행하거나, 패키지 저장소에서 설치하세요.
http://www.graphicsmagick.org/README.html#installation
- Debian/Ubuntu: $ sudo apt-get install graphicsmagick
- MacOS: $ brew install graphicsmagick
2. Dependencies: 아래 명령어를 이용해 필요한 패키지를 설치합니다.
- multiparty: multipart/form-data 형식으로 전송된 파일을 좀 더 편리하게 다룰 수 있도록 도와줍니다.
- gm: GraphicsMagick을 Node.js에서 이용할 수 있도록 도와줍니다.
npm i --save express http body-parser multiparty gm
실습
1. Sample Code: 아래 코드를 app.js로 저장합니다.
const express = require('express');
const http = require('http');
const bodyParser = require('body-parser');
const multiparty = require('multiparty');
const gm = require('gm');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
limit: '150mb',
extended: false,
}));
app.get('/', (req, res, next) => {
let contents = '';
contents += '<html><body>';
contents += ' <form action="/" method="POST" enctype="multipart/form-data">';
contents += ' <input type="file" name="image" />';
contents += ' <input type="submit" />';
contents += ' </form>';
contents += '</body></html>';
res.send(contents);
});
app.post('/', (req, res, next) => {
let contents = '';
contents += '<html>';
contents += '<head>';
contents += '<style> html{background-image: url(https://www.transparenttextures.com/patterns/ps-neutral.png); background-color: #666;} </style>';
contents += '</head>';
contents += '<body>';
contents += ' <img src="data:image/png;base64,##_CODE_##" />';
contents += '</body>';
contents += '</html>';
const form = new multiparty.Form();
form.on('part', function (part) {
gm(part)
.fuzz(10, true) // 유사 색상 선택을 위한 옵션
.transparent('#FFFFFF') // 흰색 제거
.trim() // 가장자리 빈공간 제거
.toBuffer((err, buffer) => {
contents = contents.replace(/##_CODE_##/gim, buffer.toString('BASE64'));
res.send(contents);
});
});
form.on('close', () => {});
form.on('error', () => {
res.sendStatus(500);
});
form.parse(req);
});
http.createServer(app).listen(3000, () => {
console.log('HTTP server listening on port ' + 3000);
});
app.js:38: multiparty를 이용해 Form 데이터를 처리합니다.
app.js:41: 전달된 Form 데이터를 GraphicsMagick으로 처리합니다. 파일인지 등등의 유효성 검사는 생략합니다.
app.js:42~48: 각 행은 이미지 처리 명령어입니다. 45행은 처리된 이미지를 Buffer 객체로 반환받습니다. 이 때에도 예외 처리는 생략하였습니다.
app.js:51: GraphicsMagick에서 처리가 완료된 후 페이지를 생성, 전송할 예정이므로, 빈 함수로 설정합니다.
app.js:53~55: Form 데이터 처리 중 오류가 발생하면 500 코드를 전송합니다.
2. 터미널에서 아래 명령어를 입력하면 서버가 실행됩니다.
node app.js
3. 실행된 서버에 접속하면 File을 업로드 할 수 있는 페이지가 표시됩니다.
5. 테스트 파일을 선택하고 업로드하면 흰색 배경이 지워진 결과가 표시됩니다.
GitHub
본 강의에 사용한 코드는 GitHub에 공개되어 있습니다.
https://github.com/jETA-Kor/examples
참고 문서
How I can remove background color from image using GraphicsMagick?: https://stackoverflow.com/questions/25444525/how-i-can-remove-background-color-from-image-using-graphicsmagick
GraphicsMagick: http://www.graphicsmagick.org
npm - gm: https://www.npmjs.com/package/gm