web/node.js

node.js에서 sharp를 사용해서 이미지 크기 변경하기

반응형

node.js에서 이미지 크기를 변경하기 위해서 임시 파일에 데이터를 다운로드 받고 파일 크기를 변경하는 작업을 보통 진행한다.


하지만 이번에는 html stream으로 임시로 내려받은 버퍼를 사용해서 사이즈를 변경하고 바로 s3에 전송하거나 파일로 내보내는 작업을 진행해보려한다.


이미지의 사이즈를 변경하기 위해서 필요한 라이브러리는 sharp이다. 

1
npm install sharp
cs

https://www.npmjs.com/package/sharp


먼저 request 요청으로 내려받은 image데이터를 sharp로 이미지를 변경하고 파일로 내보내보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'use strict';
 
const request = require('request-promise');
const sharp = require('sharp');
const fs = require('fs');
const Stream = require('stream').Transform;
 
class ImageResize {
 
  async imageResize() {
 
    const transformer = sharp().resize(250211);
    const writeStream = fs.createWriteStream('test.jpg');
 
    // fs.writeaStream으로 파일로 쓰기
    await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer).pipe(writeStream);
 
    // stream 처리를 통해 파일로 직접 쓰기
    this.streamToFile(await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer));
  }
 
  streamToFile (stream) {
    const chunks = new Stream();
    return new Promise((resolve, reject) => {
      stream.on('data', chunk => chunks.push(chunk));
      stream.on('error', reject);
      stream.on('end', () => fs.writeFileSync('tt.jpg', chunks.read()));
    });
  }
};
 
module.exports = new ImageResize();
cs

코드를 보면 알겠지만 생각보다 간단하다. request 요청으로 받은 html stream을 sharp로 넘겨서 처리하고 그리고 나온 스트림을 writeStream으로 넘겨서 처리하거나 별도의 스트림 처리를 설정해서 파일로 저장할 수 있다.


추가적으로 파일로 내보내는 작업이 아닌 s3로 이미지 파일을 내보내기 위해 이미지 크기가 변경된 stream을 buffer로 바꾸는 작업을 해보자. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
'use strict';
 
const request = require('request-promise');
const sharp = require('sharp');
const fs = require('fs');
const Stream = require('stream').Transform;
 
class ImageResize {
 
  async imageResize() {
 
    const transformer = sharp().resize(250211);
    const writeStream = fs.createWriteStream('test.jpg');
 
    // s3로 전송 (String)
    let dd1 = await this.streamToString(await request('https://image.toast.com/aaaaab/ticketlink/TKL_3/ion_main08061242.jpg').pipe(transformer));
 
    s3.upload({
        Body : ddl 
    });
  }
 
  streamToString (stream) {
    const chunks = [];
    return new Promise((resolve, reject) => {
      stream.on('data', chunk => chunks.push(chunk));
      stream.on('error', reject);
      stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')))
    });
  }
 
};
 
module.exports = new ImageResize();
cs


node.js stream을 이해하면 생각보다 어렵지 않은 작업으로 이미지를 임시로 저장하지 않고 바로 크기를 변경할 수 있다.


소스 git repository

https://github.com/weduls/nodejs_study


참고

https://stackoverflow.com/questions/12740659/downloading-images-with-node-js

https://stackoverflow.com/questions/10623798/writing-node-js-stream-into-a-string-variable

https://stackoverflow.com/questions/13979558/saving-an-image-stored-on-s3-using-node-js


반응형