Node 6.10.x에서 이미지 처리용으로 사용하는 lwip가 문제가 있어서, jimp로 바꿨어요.

Node LTS 버전이 6.10.3이죠. 6.9.5를 상당히 오래 쓰다가 6.10.3으로 올렸더니,
엉뚱하게 lwip에서 문제가 발생하네요.

요런 다양한 이슈들이 있습니다.
아무래도 업데이트가 너무 오래 되지 않았군요…
그래서 활성 포크인 pajk-lwip로 바꿨더니 로컬에서는 되는데, docker 환경에서 안되더군요.

결국 jimp로 바꿨습니다.

코드를 약간 수정해야했지만 native 의존성이 적어서 잘 되는군요.
성능은 1~2mb 정도인 이미지에서는 차이를 잘 모르겠네요.

코드 차이는 이정도 입니다. 훨씬 간결하고 좋네요.

lwip 버전

import lwip from 'lwip';
import stream from 'stream';

export function imageResize(file, thumbWidth = 900) {
  return new Promise((resolve, reject) => {
    const type = file.mimetype.replace('image/', '') || 'jpg';
    // read info
    lwip.open(file.path, type, (_err, _image) => {
      if (_err) return reject(_err);

      const width = _image.width();
      const height = _image.height();
      console.log('getImageSize', width, height);

      const size = {};
      size.width = thumbWidth;
      size.height = (height / width) * thumbWidth;

      // resize
      _image.resize(size.width, size.height, (_err2, _image2) => {
        if (_err2) return reject(_err2);
        // to buffer
        _image2.toBuffer('jpg', { quality: 80 }, (_err3, _buffer) => {
          if (_err3) return reject(_err3);
          // Initiate the source
          const bufferStream = new stream.PassThrough();
          // Write your buffer
          bufferStream.end(_buffer);
          // return
          resolve(bufferStream, { width, height });
        });
      });
    });
  });
}

jimp 버전

import Jimp from 'jimp';
import stream from 'stream';

export function imageResize(file, thumbWidth = 900) {
  return new Promise((resolve, reject) => {
    // read info
    Jimp.read(file.path, (_err, _image) => {
      if (_err) return reject(_err);

      const width = _image.bitmap.width;
      const height = _image.bitmap.height;
      console.log('getImageSize', width, height);

      const size = {};
      size.width = thumbWidth;
      size.height = (height / width) * thumbWidth;

      // resize
      _image.resize(size.width, size.height)
      .quality(80)
      .getBuffer(Jimp.MIME_JPEG, (_err2, _buffer) => {
        if (_err2) return reject(_err2);
        // Initiate the source
        const bufferStream = new stream.PassThrough();
        // Write your buffer
        bufferStream.end(_buffer);
        // return
        resolve(bufferStream, { width, height });
      });
    });
  });
}

jimp는 메모리를 너무 많이 먹어서… GraphicsMagick로 바꿨습니다.

gm을 적용한 코드는요…

import gm from 'gm';

export default function image() {}

export function getImageSize(file) {
  return new Promise((resolve, reject) => {
    // read info
    gm(file.path).size((_err, _size) => {
      if (_err) return reject(_err);

      console.log('getImageSize', _size);
      resolve(_size);
    });
  });
}

export function imageResize(file, resizedWidth = 900) {
  return new Promise((resolve, reject) => {
    // read info
    gm(file.path).size(function (_err, _size) {
      if (_err) return reject(_err);

      const width = _size.width;
      const height = _size.height;
      console.log('getImageSize', width, height);

      const size = {};
      // crop position
      if (width > height) {
        // landsacpe : 3000 * 2000
        size.width = (width / height) * resizedWidth; // 1.5 * 300 = 450
        size.height = resizedWidth; // 300
      } else {
        // portrait : 2000 * 3000
        size.width = resizedWidth;  // 300
        size.height = (height / width) * resizedWidth;  // 1.5 * 300 = 450
      }

      // resize
      const stream = this.resize(size.width, size.height)
        .quality(80)
        .stream();

      resolve({ stream, ...size });
    });
  });
}
1개의 좋아요

동우님은 parse-server 사용할 때 이를 이용해서 서버사이드에서 thumbnail 생성하고 계신건가요?

네. 서버에서 썸네일 생성하고 있습니다. Lamda도 써보고 했지만, 제일 깔끔한건 역시 서버코드로 만드는거더라구요.

1개의 좋아요