使用jsdom或Canvas为node.js获取Vibrant.js样本

HP.*_*HP. 5 javascript canvas image node.js jsdom

我有一个使用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';
Run Code Online (Sandbox Code Playgroud)

使用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';

});
Run Code Online (Sandbox Code Playgroud)

我可以在Vibrant.js中使用URL,但这是使用Bluebird的另一个http GET,我需要避免再次调用网络进行下载.

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

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

EMX*_*EMX 2

正确构建缓冲区

encoding:null 返回缓冲区而不是字符串。(字符串给你无法使用的乱码数据

const Vibrant = require('node-vibrant');
const request = require('request').defaults({encoding:null});

doRequest('https://i.stack.imgur.com/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))
  })
}
Run Code Online (Sandbox Code Playgroud)

额外:使用 JIMP

Vibrant 构造函数的imagePatharg 直接传递给抽象 Image 构造函数(NodeImage在 NodeJS 环境中并NodeImage使用Jimp

/*:USING JIMP:*/
doJimpRequest('https://i.stack.imgur.com/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))
    })
  });
}
Run Code Online (Sandbox Code Playgroud)