Node.js : ImageMagick없이 이미지 크기 조정


85

저는 Node.js (+ express 4)에서 사용자가 프로필 이미지를 서버에 업로드하여 설정할 수있는 웹 앱을 개발 중입니다. 우리는 이미 파일 MIME 유형과 최대 파일 크기를 제한하므로 사용자는 200KB 이상의 png 또는 jpeg 이미지를 업로드 할 수 없습니다.

문제는 업로드 된 이미지 해상도를 200x200으로 크기를 조정 (서버 측)하여 페이지 로딩을 개선하고 디스크 공간을 절약하고자한다는 것입니다. 몇 가지 조사 후 모든 답변은 ImageMagick 또는 GraphicsMagick을 기반으로 한 모듈을 사용하는 것으로 나타났습니다.

그러나 간단한 이미지 크기 조정을 수행하기 위해 ImageMagick / GraphicsMagick을 설치해야하는 것은 나에게 너무 지나친 것처럼 보이므로 Node.js에 대해 이것 이외의 다른 솔루션이 있습니까?

편집 : 이전 솔루션 (lwip)이 더 이상 유지되지 않으므로 수락 된 솔루션을 sharp 로 변경했습니다 . 모든 피드백에 감사드립니다!


안녕하세요. 질문이 있습니다. 이미지 크기를 200KB 이하로 줄이는 방법은 무엇입니까? 길을 설명 해주세요. 감사.
C.Petrescu

안녕하세요, 이전에 게시 된 관련 질문을 찾지 못한 경우 해당 질문을 새 질문으로 게시 할 가치가 있습니다. 약간의 정보를 제공하려면이 질문에서 찾을 수있는 도구에 대해 제공된 API에서 압축 및 크기 조정 방법을 찾아보십시오.
zacr0

답변:


92

나는 sharp에 투표 할 것입니다 .

sharp('input.jpg')
  .resize(200, 200)
  .toFile('ouput.jpg', function(err) {
    // output.jpg is a 200 pixels wide and 200 pixels high image
    // containing a scaled and cropped version of input.jpg
  });

그것은 빠르고, 일반적으로 6 배 빠른 가장 빠른 ImageMagick를 기반 노드 바인딩에 비해 , 매우 작은 메모리에서 실행, 아마 적은 10 배 . libvips 이미지 라이브러리 에 대한 날카로운 링크 , 외부 프로그램에 대한 쉘링이 없으며 라이브러리 자체가이 작업에서 * magick보다 빠르고 효율적입니다. 스트림, 버퍼 및 파일 시스템 입력 및 출력, 색상 관리, 투명성, 약속, 오버레이, WebP, SVG 등과 같은 유용한 기능을 지원합니다.

Sharp 0.20부터 npm은 대부분의 플랫폼에서 사전 컴파일 된 완전한 바이너리를 자동으로 다운로드하므로 node-gyp이 필요하지 않습니다. 다음을 입력하십시오.

npm install sharp

또는:

yarn add sharp

그리고 가세요.


7
v0.12.0부터는 sharp사전 컴파일 된 libvip 버전을 번들로 제공하므로 더 이상 Linux 및 Windows 사용자를위한 외부 런타임 종속성이 없습니다. 크기 조정 작업은 LWIP보다 약 10 배 빠르며 메모리 사용량의 일부로도 빠릅니다.
Lovell Fuller

4
날카로운 네이티브 GIF 및 버전 0.15와 SVG 지원 추가 sharp.dimens.io/en/stable/changelog
jcupitt

1
수백 개의 파일이지만 모두 npm에 의해 자동으로 관리되므로 생각할 필요가 없습니다.
jcupitt 2016-10-05

4
@CoDEmanX 아마도 npm install --global --production windows-build-tools먼저 실행 해보십시오 . 참조 github.com/Microsoft/nodejs-guidelines/blob/master/…
Lovell Fuller

1
나는 약간의 스크립트를 만들어서 어떤 일이 일어나고 있는지 , 부 스트랩 카드 및 배경과 같은 콘텐츠에서 어떻게 보이는지 쉽게 확인할 수 있습니다. 매개 변수를 가장 최적화하기위한 커버, 아마도 intrest github.com/lcherone/sharp-test
Lawrence Cherone

71

최근에 런타임 종속성없이 NodeJS 용 이미지 처리 모듈을 개발하기 시작했습니다 ( 이유 읽기 ). 아직 초기 단계이지만 이미 사용할 수 있습니다.

귀하가 요청하는 것은 다음과 같이 수행됩니다.

image.resize(200, 200, function(err, image){
    // encode resized image to jpeg and get a Buffer object
    image.toBuffer('jpg', function(err, buffer){
        // save buffer to disk / send over network / etc.
    });
});

모듈의 Github repo 에서 더 많은 정보를 확인하세요 .


7
귀하의 모듈은 굉장합니다. 그러나 너무 많은 메모리가 필요합니다. 나는에 시도했다 이미지, 그리고 메모리 130MB가 필요합니다. 그 후 이미지를 여러 개의 썸네일 (640,560,480, ..., 160) 크기로 조정하여 테스트를 했는데 메모리 용량은 약 1.7GB입니다. 그게 버그인가요? writeFile1.8Mb4MB, 11000x6000
Lewis

2
안녕하세요 @Orion, 피드백 감사합니다. Github 리포지토리로 이동하여 더 자세한 정보 (OS, 버전, 코드를 재현하기위한 코드)가있는 문제를여십시오. 우리는 :)이 함께 해결하려고합니다
EyalAr

@EyalAr 안녕하세요 Eyal, 크기를 조정하고 측면을 유지하는 방법? 연신하지 않고 (폭, 높이의 최대 가능한 크기로 크기 조정)
다니엘 KROM를

10
2017 년에는 lwip을 사용하지 않는 것이 좋습니다.이 패키지는 더 이상 지원되지 않는 것으로 보이며 Windows 및 현재 Unix 플랫폼에서도 대규모 설치 문제가 있습니다.
zerefel

9
lwip은 불행히도 죽은 프로젝트입니다. 날카로운 그러나 여전히 적극적으로 유지되는 것 같습니다.
laurent

16

lwip 살펴보기 : https://github.com/EyalAr/lwip

매우 간단하고 사용하기 쉽습니다.

npm install lwip

그런 다음 노드 코드에서

// obtain an image object:
require('lwip').open('image.jpg', function(err, image){

  // check err...
  // define a batch of manipulations and save to disk as JPEG:
  image.batch()
    .scale(0.75)          // scale to 75%
    .rotate(45, 'white')  // rotate 45degs clockwise (white fill)
    .crop(200)            // crop a 200X200 square from center
    .blur(5)              // Gaussian blur with SD=5
    .writeFile('output.jpg', function(err){
      // check err...
      // done.
    });

});

파일 업 로더 에서 성공적으로 구현 했으며 매력처럼 작동합니다.


1
이것은 이미지 크기 조정과 관련된 몇 가지 기능에 대해 과도하고 무거운 외부 종속성을 설치할 필요없이 제가 찾고 있던 것입니다.
zacr0 2014 년

3
Btw @EyalAr은이 노드 모듈의 작성자입니다. 그의 의견도 아래에 나열되어 있습니다.
Arvind 2014

설치 및 작업이 매우 직관적입니다. ImageMagick과 같은 바이너리 라이브러리를 구현할 필요가 없다는 점이 정말 마음에 듭니다.
ChrisRich

이 답변 (lwip 소유자)과 정확히 동일하지만 나중에 : stackoverflow.com/a/24543924/1525495
Jorge Fuentes González

12

다른 라이브러리 인 Jimp에 대한 종속성없이 완전히 JavaScript로 작성된 좋은 이미지 조작 라이브러리가 있습니다. https://github.com/oliver-moran/jimp

사용 예 :

var Jimp = require("jimp");

// open a file called "lenna.png"
Jimp.read("lenna.png", function (err, lenna) {
    if (err) throw err;
    lenna.resize(256, 256)            // resize
         .quality(60)                 // set JPEG quality
         .write("lena-small.jpg"); // save
});

ImageMagik에 비해 얼마나 빠릅니까?
Christopher Grigg

2
sharp에는 일련의 벤치 마크가 있습니다. sharp.dimens.io/en/stable/performance ---이 테스트에서 jimp는 IM보다 5 배 느리고 sharp보다 30 배 느립니다. 물론 충분히 빠르면 충분히 빠르며 속도 만 고려해야 할 요소는 아닙니다.
jcupitt

실시간은 아닐 수도 있지만 Jimp는 여러 크기의 썸네일 파일을 작성하고 나중에 캐시 된 파일로 검색하는 데 아주 좋습니다.
coderofsalvation 2017 년

jimp는 webp를 지원하지 않으며 가까운 장래에 지원하지 않을 것입니다. 참조 : github.com/oliver-moran/jimp/issues/144
Viacheslav Dobromyslov

8

sharp 는 최근 인기를 얻었지만 * Magick 바인딩과 같은 아이디어입니다.

그러나 간단한 이미지 크기 조정을 위해 ImageMagick / GraphicsMagick을 설치해야하는 것은 나에게 너무 과한 것 같습니다.

이미지 크기 조정은 간단하지 않습니다. JPEG 형식은 특히 복잡하며 다양한 품질의 결과로 그래픽 크기를 조정하는 여러 가지 방법이 있으며 그 중 일부는 쉽게 구현할 수 있습니다. 이 작업을 수행하기 위해 이미지 처리 라이브러리가 존재하므로 설치할 수없는 다른 이유가 없다면 사용하십시오.


13
저는 게으른 개발자 일 수도 있지만 ImageMagick의 설치 프로세스를보고 Amazon AWS EC2 인스턴스에 설치하는 데 얼마나 많은 비용이 들었는지 궁금해하자마자 즉시 다른 옵션을 찾기 시작했습니다. 축소판 이미지의 크기를 조정하는 기능.
ChrisRich

7

Canvas는 ImageMagic보다 2.3 배 빠릅니다 .

당신은 이미지 조작을위한 Node.js를 모듈을 비교하기 위해 시도 할 수 있습니다 - https://github.com/ivanoff/images-manipulation-performance

author's results:
 sharp.js : 9.501 img/sec; minFreeMem: 929Mb
 canvas.js : 8.246 img/sec; minFreeMem: 578Mb
 gm.js : 4.433 img/sec; minFreeMem: 791Mb
 gm-imagemagic.js : 3.654 img/sec; minFreeMem: 804Mb
 lwip.js : 1.203 img/sec; minFreeMem: 54Mb
 jimp.js : 0.445 img/sec; minFreeMem: 82Mb

3

큰 이미지가 필요하지 않은 경우 업로드하기 전에 클라이언트 측에서 크기를 조정할 수 있습니다.

File API를 사용하여 JavaScript에서 파일 읽기

서버에 업로드하기 전에 자바 스크립트로 클라이언트 측 이미지 크기 조정

많은 사용자가 스마트 폰에서 자신의 모습을 잘 볼 수 있으며 그중 많은 사용자가 200KB 이상입니다. 클라이언트가 제공 한 데이터는 신뢰할 수 없으므로 서버 측 검사가 계속 적용됩니다.


2
클라이언트를 신뢰할 수 없습니다. 사용자는 업로드 끝점을 알고 있어야 원하는 것을 보낼 수 있습니다. 따라서 파일 크기와 같은 유효성 검사가 계속 적용됩니다. 그러나 클라이언트 측에서 크기를 조정하는 것은 좋은 생각입니다.
Kev 2015 년

1

lwip (이전에 arvind에서 제안한대로)를 사용하고 있었지만 png-crop 로 전환했습니다 . 나를 위해 조금 더 빠르게 작동하는 것 같습니다 (Win 8.1 x64, Node v0.12.7). 리포지토리의 코드는 매우 가볍고 운영상 사용이 간편합니다.

var pngcrop = require('png-crop');
var config = {left: 10, top: 100, height: 150, width: 150};
pngcrop.crop('cats.png','cats-cropped.png',config);

물론 png 파일 만 수행합니다.


0

날카로운 작업은 매우 잘 작동하고 스트림과 함께 사용하기 쉽고 매력처럼 작동하지만 노드 버전으로 컴파일해야합니다. 이것은 단점입니다. AWS S3 버킷의 이미지로 Sharp를 이미지 처리에 사용하고 있었고 완벽하게 작동했지만 다른 모듈을 사용해야했습니다. GM은 나를 위해 일하지 않았지만 Jimp는 매우 잘했습니다!

쓰여진 그림의 경로에주의를 기울여야합니다. 경로를 "/"로 시작하면 오류가 발생할 수 있습니다.

이것이 nodeJS에서 Jimp를 사용한 방법입니다.

const imageUrl = `SOME_URL`;
let imgExported = 'EXPORTED_PIC.png';

Jimp.read(imageUrl)
    .then(image => {
        image   
            .resize(X, Y) 
            .write(`tmp/`+ imgExported, err => { 
                if(err) 
                    console.error('Write error: ', err);
                else { ... // don't forget to put a callback() } }

            });

또한 실행 순서를 조심하고 원하지 않을 때 다른 일이 발생하지 않도록 콜백을 넣으십시오. Jimp.read ()에 대해 "await"를 사용해 보았지만 제대로 작동하지 않았습니다.


Sharp 0.20부터 대부분의 플랫폼에서 정확한 노드 버전에 대해 사전 컴파일 된 바이너리를 자동으로 다운로드하므로 아무것도 빌드 할 필요가 없습니다.
jcupitt

불행히도 그것은 나를 위해 작동하지 않았습니다. 다양한 node.js 버전이있는 읽기 전용 파일 시스템에서 sharp를 사용해야했고 사용중인 각 노드 버전에 대한 sharp 모듈을 다운로드해야했고 시간이 너무 많이 걸렸습니다.
Alex Seceleanu

0

jimp (node_module)를 사용하여이 작업을 수행 할 수 있습니다.

로컬 쓰기 :

Jimp.read(path) // this can be url or local location
      .then(image=> {
          image
            .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd
            .write('path-to-save');
      })
      .catch(err => {
        console.log(err);
      });

s3 또는 원하는 곳에 업로드합니다.

Jimp.read(urls) // this can be url or local location
          .then(image=> {
              image
                .resize(size, Jimp.AUTO) // jimp.AUTO automatically sets the width so that the image doesnot looks odd
                .getBase64(Jimp.AUTO, (err, res) => {
                  const buf = new Buffer(
                    res.replace(/^data:image\/\w+;base64,/, ""),
                    "base64"
                  );
                  var data = {
                    Key: key,
                    Bucket: bucket,
                    Body: body,
                    ContentEncoding: "base64",
                    ContentType: "image/jpeg"
                  };
                  s3.putObject(data, function(err, data) {
                    if (err) {
                      throw err;
                    } else {
                      console.log("succesfully uploaded the image!");
                    }
                  });
                });
          })
          .catch(err => {
            console.log(err);
          });

0

단순성을 위해 resize-img 라이브러리를 좋아 합니다.

const fs = require('fs');
const resizeImg = require('resize-img');

(async () => {
    const image = fs.readFileSync('unicorn.png');

    const newImage = await resizeImg(image, { width: 128, height: 128 });

    fs.writeFileSync('unicorn-128x128.png', newImage);
})();

0

Google Drive API v3를 사용하여 이미지 크기 조정을 구현했습니다 . 이 방법은 Google Apps Script에서 Google 스프레드 시트에 이미지를 삽입하는 데 권장됩니다.

알고리즘 :

  1. Google 드라이브 폴더에 이미지를 업로드 합니다.
  2. 가져 오기 공공 URL 썸네일 이미지를.
  3. URL의 'resize'매개 변수를 필요한 너비 및 / 또는 높이로 바꿉니다. (기본 썸네일 크기는 220px입니다).
  4. Google 드라이브에서 크기가 조정 된 썸네일을 다운로드합니다.

예를 보려면 https://github.com/dobromyslov/google-drive-utils/blob/511c44c2c48862b47c60038423b7f71bf1d28f49/src/index.ts#L150

그리고 GDrive 할당량에 유의하십시오.

  • 일일 쿼리 : 1000000000
  • 사용자 당 100 초당 쿼리 : 1000
  • 100 초당 쿼리 : 10000
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.