Node.js: ImageMagick के बिना आकार बदलने वाली छवि


85

मैं Node.js (+ एक्सप्रेस 4) पर एक वेब ऐप विकसित कर रहा हूं, जहां उपयोगकर्ता सर्वर पर अपलोड करके अपनी प्रोफ़ाइल छवि सेट कर सकते हैं। हम पहले से ही फ़ाइल mimetype और अधिकतम फ़ाइलों को सीमित करते हैं, इसलिए उपयोगकर्ता 200KB पीएनजी या जेपीईजी छवियों को अपलोड नहीं कर सकता है।

समस्या यह है कि हम पृष्ठ पर लोडिंग और बचत स्थान को सुधारने के लिए 200x200 पर अपलोड की गई छवि रिज़ॉल्यूशन (सर्वरसाइड) को आकार बदलना चाहेंगे। कुछ शोधों के बाद, सभी उत्तरों ने ImageMagick या GraphicsMagick के आधार पर किसी भी मॉड्यूल का उपयोग करने के लिए कहा।

हालाँकि, एक साधारण छवि का आकार बदलने के लिए ImageMagick / GraphicsMagick स्थापित करने के लिए मेरे लिए बहुत अधिक लगता है, इसलिए, क्या Node.js के अलावा कोई अन्य समाधान है?

संपादित करें: मैंने स्वीकार किए गए समाधान को तेज करने के लिए बदल दिया है क्योंकि पिछले समाधान (lwip) को अब बनाए नहीं रखा गया है। अपने सभी फ़ीडबैक के लिए शुक्रिया!


नमस्ते। मेरा एक सवाल है। 200KB से नीचे की छवि का आकार कैसे कम करें? कृपया, रास्ते के बारे में बताएं। धन्यवाद।
सी.पटेरेस्क्यू

नमस्कार, यह सवाल एक नए के रूप में पोस्ट करने के लायक है यदि आपको कोई संबंधित नहीं मिला है जो पहले पोस्ट किया गया था। आपको कुछ प्रकाश देने के लिए, इस प्रश्न में मिल सकने वाले उपकरणों के लिए दिए गए एपीआई में संपीड़न और आकार देने के तरीकों की तलाश करें।
zacr0

जवाबों:


92

मैं तेज वोट करूंगा :

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
  });

यह तेज़ है, आम तौर पर सबसे तेज़ इमेजमैगिक-आधारित नोड बाइंडिंग से 6x तेज है , और बहुत कम मेमोरी में चलता है, शायद 10x कमlibvips छवि लाइब्रेरी के लिए सीधे लिंक , कोई बाहरी प्रोग्राम करने के लिए कोई शेलिंग नहीं है, और लाइब्रेरी स्वयं इस कार्य में * magick की तुलना में अधिक तेज़ और अधिक कुशल है। यह धारा, बफर और फाइलसिस्टम इनपुट और आउटपुट, रंग प्रबंधन, पारदर्शिता, वादे, ओवरले, वेबपी, एसवीजी, और अधिक जैसी उपयोगी चीजों का समर्थन करता है।

तेज 0.20 के रूप में, एनपीएम स्वचालित रूप से अधिकांश प्लेटफार्मों पर पूर्ण-संकलित बायनेरिज़ को डाउनलोड करेगा, इसलिए नोड-जिप की कोई आवश्यकता नहीं है। बस दर्ज करें:

npm install sharp

या:

yarn add sharp

और तुम जाओ।


7
V0.12.0 के रूप में, sharpअब लिनक्स और विंडोज उपयोगकर्ताओं के लिए कोई बाहरी रनटाइम निर्भरता नहीं है क्योंकि यह libvips के पूर्व-संकलित संस्करण को बंडल करता है। आप पाएंगे कि आकार बदलने वाले ऑपरेशन LWIP की तुलना में ~ 10x तेज हैं और मेमोरी उपयोग के एक अंश पर हैं।
लवले फुलर

4
संस्करण 0.15 sharp.dimens.io/en/stable/changelog
jcupitt

1
यह फ़ाइलों की 100s है, लेकिन वे सभी आपके लिए npm द्वारा स्वचालित रूप से प्रबंधित हैं, आपको इसके बारे में सोचने की आवश्यकता नहीं है।
jcupitt

4
@CoDEmanX शायद npm install --global --production windows-build-toolsपहले दौड़ने का प्रयास करें । यह भी देखें github.com/Microsoft/nodejs-guidelines/blob/master/...
लोवेल फुलर

1
मैं बनाया एक छोटे से स्क्रिप्ट आसान बनाता है देखना क्या बातें कर रहे हैं और यह बूटस्ट्रैप कार्ड और पृष्ठभूमि की तरह सामग्री में इस तरह दिखाई देंगे: सबसे अच्छा अनुकूलन करने के लिए कवर पैरामीटर, हो सकता है इसकी की ब्याज github.com/lcherone/sharp-test
लॉरेंस 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 रेपो में अधिक जानकारी ।


7
आपका मॉड्यूल कमाल का है। हालाँकि, यह इतना मेमोरी लेता है। मैंने writeFile एक 1.8Mbछवि की कोशिश की है , और इसके लिए 130Mb मेमोरी की आवश्यकता है। उसके बाद, मैं एक 4MB, 11000x6000चित्र को कई थंबनेल (640,560,480, ..., 160) का आकार देकर परीक्षण करता हूं और इसमें लगभग 1.7GB मेमोरी लगती है। क्या वह बग है?
लुईस

2
हाय @ धन्यवाद, प्रतिक्रिया के लिए धन्यवाद। कृपया गितुब रेपो को देखें और कुछ और विवरणों (ओएस, संस्करण, कोड को पुन: उत्पन्न करने के लिए) के साथ एक समस्या खोलें। हम इसे एक साथ हल करने की कोशिश करेंगे :)
EyalAr

@ ईयाल अरे, ईयाल, आकार और पहलू कैसे रखें? (बिना स्ट्रेचिंग के अधिकतम संभव आकार, चौड़ाई का आकार)
डैनियल क्रॉम

10
मैं 2017 में lwip का उपयोग नहीं करने का सुझाव दूंगा। पैकेज का अब समर्थन नहीं लगता है और इसमें विंडोज पर और अब यूनिक्स प्लेटफार्मों पर भी बड़े पैमाने पर इंस्टॉलेशन मुद्दे हैं।
ज़ेरेफ़ेल

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

3
Btw @EyalAr इस नोड मॉड्यूल का लेखक है। उनकी टिप्पणी भी नीचे सूचीबद्ध है।
अरविंद

बहुत सहज स्थापित करने और साथ काम करने के लिए। मुझे वास्तव में पसंद है कि आपको ImageMagick जैसी किसी भी बाइनरी लाइब्रेरी को लागू करने की आवश्यकता नहीं है।
क्रिसरिच

यह इस उत्तर (lwip मालिक) के समान ही है, लेकिन बाद में: stackoverflow.com/a/24543924/1525495
जॉर्ज फ्यूएंटेस गोंजालेज

12

एक अच्छी छवि हेरफेर लाइब्रेरी है जो पूरी तरह से जावास्क्रिप्ट में लिखी जाती है, बिना किसी अन्य लाइब्रेरी, जिम्प पर निर्भरता के। 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 की तुलना में यह कितना तेज है?
क्रिस्टोफर ग्रिग ने

2
शार्प में बेंचमार्क का एक सेट होता है: sharp.dimens.io/en/stable/performance --- उस परीक्षण पर, आईएम आईएम की तुलना में 5x धीमा और तेज की तुलना में 30x धीमा होता है। बेशक, उपवास पर्याप्त पर्याप्त है, और गति केवल विचार करने का कारक नहीं है।
जूलिट

रीयलटाइम शायद नहीं, लेकिन जिम्प केवल कई-आकार के थंबनेल-फ़ाइलें लिखने के लिए भयानक है (और बाद में कैश्ड फ़ाइलों के रूप में उन्हें पुनः प्राप्त करें)।
कोडरफॉस्लेशन

जिम्प वेब का समर्थन नहीं करता है और निकट भविष्य में समर्थन नहीं करेगा। देखें: github.com/oliver-moran/jimp/issues/144
Viacheslav Dobromyslov

8

तेज ने हाल ही में कुछ लोकप्रियता का आनंद लिया है, लेकिन यह * मैजिक बाइंडिंग * के समान है।

हालाँकि, एक साधारण छवि का आकार बदलने के लिए ImageMagick / GraphicsMagick स्थापित करने के लिए मेरे लिए बहुत अधिक लगता है

इमेज का आकार बदलना सरल लेकिन कुछ भी है। जेपीईजी प्रारूप विशेष रूप से जटिल है, और अलग-अलग गुणवत्ता के परिणामों के साथ ग्राफिक्स को स्केल करने के कई तरीके हैं, उनमें से कुछ आसानी से लागू होते हैं। इमेज प्रोसेसिंग लाइब्रेरी इस काम को करने के लिए मौजूद हैं, इसलिए यदि कोई अन्य कारण नहीं है कि आप उन्हें स्थापित क्यों नहीं कर सकते हैं, तो इसके लिए जाएं।


13
शायद मैं एक आलसी डेवलपर हूं, लेकिन जैसे ही मैंने ImageMagick के लिए इंस्टॉलेशन प्रक्रिया देखी और सोच रहा था कि मैं इसे अपने अमेज़ॅन AWS EC2 उदाहरण पर स्थापित करने में कितना खर्च करूंगा, मैंने तुरंत अन्य विकल्पों की तलाश शुरू कर दी - विशेष रूप से यह देखते हुए कि मुझे सभी की आवश्यकता थी थंबनेल के लिए छवियों का आकार बदलने की क्षमता।
क्रिसरिख

7

कैनवस 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

यदि आपको एक बड़ी छवि की आवश्यकता नहीं है, तो आप इसे अपलोड करने से पहले ग्राहक की ओर से इसका आकार बदल सकते हैं:

फ़ाइल एपीआई का उपयोग करके जावास्क्रिप्ट में फाइल पढ़ना

सर्वर पर अपलोड करने से पहले जावास्क्रिप्ट के साथ क्लाइंट-आकार का चित्र

कई उपयोगकर्ताओं के पास स्मार्टफोन से खुद की एक अच्छी तस्वीर हो सकती है, और उनमें से कई 200kB से अधिक हैं। ध्यान दें कि क्लाइंट-प्रदत्त डेटा पर भरोसा नहीं करना है, इसलिए सर्वर-साइड चेक अभी भी लागू होते हैं।


2
आप कभी भी ग्राहक पर भरोसा नहीं कर सकते हैं, एक उपयोगकर्ता को जो कुछ भी वह चाहता है उसे भेजने के लिए अपलोड समापन बिंदु जानने की जरूरत है। इसलिए, फ़ाइल आकार जैसी मान्यताएँ अभी भी लागू होती हैं। लेकिन, ग्राहक पक्ष पर आकार बदलना एक अच्छा विचार है।
केव

1

मैं lwip का उपयोग कर रहा था (जैसा कि पहले arvind द्वारा सुझाया गया था) लेकिन png- फसल पर स्विच किया गया । यह मेरे लिए थोड़ा तेज़ काम करता है (विन 8.1 x64, नोड 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

तीव्र काम बहुत अच्छी तरह से और धाराओं के साथ उपयोग करना आसान है, एक आकर्षण की तरह काम करते हैं, लेकिन आपको इसे नोड संस्करण के साथ संकलित करने की आवश्यकता है, यह इसके लिए एक नकारात्मक पहलू है। मैं छवि प्रसंस्करण के लिए तीव्र का उपयोग कर रहा था, एडब्ल्यूएस एस 3 बाल्टी से एक छवि के साथ और पूरी तरह से काम किया, लेकिन मुझे दूसरे मॉड्यूल का उपयोग करना पड़ा। जीएम ने मेरे लिए काम नहीं किया, लेकिन जिम्प ने बहुत अच्छा काम किया!

आपको लिखित चित्र के पथ पर ध्यान देना होगा, यदि आप पथ को "/" से शुरू करते हैं तो यह आपको कुछ त्रुटियां दे सकता है।

इस तरह से मैंने नोडज में जिम्प का उपयोग किया:

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 () के लिए "प्रतीक्षा" का उपयोग करने की कोशिश की, लेकिन यह अच्छी तरह से काम नहीं किया।


0.20 तेज से, यह स्वचालित रूप से अधिकांश प्लेटफार्मों पर आपके सटीक नोड संस्करण के लिए पूर्व-संकलित बाइनरी डाउनलोड करेगा, इसलिए कुछ भी बनाने की आवश्यकता नहीं है।
19 '12

दुर्भाग्य से यह मेरे लिए काम नहीं किया। मुझे विभिन्न नोड.जेएस संस्करणों के साथ एक रीड ओनली फाइल सिस्टम में शार्प का उपयोग करने की आवश्यकता थी और मुझे प्रत्येक नोड संस्करण के लिए शार्प मॉड्यूल डाउनलोड करना था जो मैं उपयोग कर रहा था और इसमें बहुत अधिक समय लग रहा था।
एलेक्स सेलेन्यू

0

आप इसे जिम्प (नोड_मॉड्यूल) का उपयोग करके कर सकते हैं

स्थानीय लिखें:

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

मैं अपनी सादगी के लिए आकार बदलने के लिए पुस्तकालय की तरह है ।

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 डिस्क API v3 का उपयोग करके कार्यान्वित छवि का आकार बदल जाता है । Google Apps स्क्रिप्ट में Google पत्रक में चित्र सम्मिलित करने के लिए इस विधि की अनुशंसा की जाती है।

algorythm:

  1. Google ड्राइव फ़ोल्डर में छवि अपलोड करें
  2. छवि थंबनेल सार्वजनिक URL प्राप्त करें।
  3. आवश्यक चौड़ाई और / या ऊंचाई वाले URL में 'आकार बदलें' पैरामीटर बदलें। (डिफ़ॉल्ट थंबनेल आकार 220px है)।
  4. Google ड्राइव से डाउनलोड किए गए थंबनेल डाउनलोड करें।

यहां देखें उदाहरण: https://github.com/dobromyslov/google-drive-utils/blob/511c44c2c48862b47c60038423b7f71bf1d28f49/rc/index.ts#L150

और GDrive कोटा से सावधान रहें:

  • प्रति दिन प्रश्न: 1000000000
  • उपयोगकर्ता प्रति 100 सेकंड में प्रश्न: 1000
  • प्रति सेकंड 100 प्रश्न: 10000
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.