Node.js에서 Canvas (ImageData)를 사용한 간단한 이미지 처리

배경



이미지를 처리 ​​할 때 HTML5의 Canvas의 ImageData가 형식이나 의식없이 픽셀 단위로 액세스 할 수있어 쉽습니다!
Node만으로는 할 수 없을까라고 생각하면 node-canvas를 사용하는 것으로 할 수 있었습니다.

추가



Node에서 이미지 괴롭히는 일을하는 사람은 마조 밖에 없습니다. 보통 사람은 OpenCV라든지 사용합시다.

ImageData란?



HTML5의 Canvas를 JavaScript로 취급할 때의 화상의 화소치의 배열 같은 것입니다.
아래 카약 사람이 쓴 기사를 알기 쉽기 때문에 참조하십시오.
canvas를 바이트 단위로 수정하는 방법 (ImageData 사용법)

환경



Windows10에서 Vagrant를 사용하여 가상 머신을 만들었습니다.
가상 머신의 OS는 ubuntu/trusty64을 사용했습니다.
Node.js를 그대로 넣으면 명령이 "node"가 아니라 "nodejs"가되어 버리기 때문에 심볼릭 링크를 작성하고 있습니다.

우분투에 설치하는 경우
$ sudo apt-get install nodejs -y
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
$ sudo apt-get install npm -y

사전 준비



node-canvas 을 사용합니다.
cario를 사용하므로 먼저 설치하고 나서 npm에서 임의의 장소에 node-canvas를 넣을 수 있습니다.

우분투에 설치하는 경우
$ sudo apt-get install libcairo2-dev
$ npm install canvas

컬러 이미지를 의사 흑백으로 사용



실제로 화상( 프로 생 )을 읽어, 화상 처리를 실시해 파일로서 출력해 봅니다. node canvas_test.js 를 실행하면 같은 디렉토리의 "pronama.png"에서 의사 단색 이미지 "monochrome.png"를 출력합니다.

이런 느낌이 듭니다.
처리 전 (pronama.png)


처리 후 (monochrome.png)


코드



canvas_test.js
// Node.js標準装備のファイルの読み書きするやつ
var fs = require('fs');

// 別途用意した画像を保存してくれるやつ
var canvas_saver = require('./canvas_saver.js');

// node-canvas
var Canvas = require('canvas'),
    Image = Canvas.Image;

fs.readFile(__dirname + '/pronama.png', function(err, data){
    if (err) throw err;

    // データをcanvasのcontextに設定
    var img = new Image;
    img.src = data;
    var canvas = new Canvas(img.width, img.height);
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, img.width, img.height);

    // RGBの画素値の配列を取得
    var imagedata = ctx.getImageData(0, 0, img.width, img.height);

    // 画像加工(擬似モノクロ化)
    for(var y=0; y<imagedata.height; y++){
        for(var x=0; x<imagedata.width; x++){
            var index = (y*imagedata.width+x)*4;
            // imagedata.data[index] = imagedata.data[index]; // R
            imagedata.data[index+1] = imagedata.data[index]; // G
            imagedata.data[index+2] = imagedata.data[index]; // B
            // imagedata.data[index+3]; // alpha
        }
    }

    // 加工したデータをセット
    ctx.putImageData(imagedata, 0, 0);

    // データを保存
    canvas_saver.save(canvas, "monochrome.png", function(){
        console.log("画像保存完了したよ!!");
    });

});

canvas_saver.js
// node-canvasのcanvasを画像データとして保存する

module.exports = (function(){
    "use strict";

    var fs = require('fs');

    var canvas_to_base64 = function(canvas){
        return canvas.toDataURL().split(',')[1];
    }

    // 追記: もっと簡単にできる方法がたしかあります(その方法は忘れました)
    var decode_and_copy = function(string, filename, callback) {
        var buffer = new Buffer(string, 'base64');
        fs.writeFile(filename, buffer, callback);
    }

    return {
        save: function(canvas, name, callback){
            decode_and_copy(
                canvas_to_base64(canvas),
                name,
                callback
            );
        }
    }

})();

기타 예



ImageData 를 취득하는 것에 의해, 이미지의 헤더나 포맷을 의식하지 않고 이미지의 픽셀치를 트위스트할 수 있습니다.
예를 들면, 의사 모노크로화의 부분을 이하와 같이 재기록하면 간단하게 네가포지 반전의 처리를 실시할 수 있습니다.

부정적인 반전
imagedata.data[index] = 255 - imagedata.data[index]; // R
imagedata.data[index+1] = 255 - imagedata.data[index+1]; // G
imagedata.data[index+2] = 255 - imagedata.data[index+2]; // B
// imagedata.data[index+3]; // alpha

요약



node-canvas를 이용하여, 웹상의 Canvas의 취급과 같이 화상 처리를 실시할 수 있었다.

참고 문헌 등



node-canvas
canvas를 바이트 단위로 수정하는 방법 (ImageData 사용법)
서버 측에서 Canvas 사용 (node.js)
프로 생
ImageData 사양

기타



실수나 의견 등이 있으시면, 꼭 코멘트해 주세요.

홍보



따라주세요 @redshoga

좋은 웹페이지 즐겨찾기