이미지 파일의 배경색을 제거하기

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