Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support img.src = <url> #945

Closed
Stomp1998 opened this issue Jul 24, 2017 · 5 comments
Closed

Support img.src = <url> #945

Stomp1998 opened this issue Jul 24, 2017 · 5 comments
Labels

Comments

@Stomp1998
Copy link

Give me a example i stuck in pleaaz

@jhuckaby
Copy link
Contributor

I assume you are asking how to load an image into node-canvas from a URL? You first have to use an HTTP client library to fetch the URL, and get yourself a Buffer object containing the binary image data in the HTTP response, then pass that to the node-canvas Image src property.

Here is an example using my own pixl-request HTTP library, but there are tons of others available which can do this as well (request, got, superagent, etc.).

var fs = require('fs');
var Request = require('pixl-request');
var Canvas = require('canvas');
var Image = Canvas.Image;

var url = "http://placehold.it/256x256/0000ff/ffffff&text=node-canvas";

var request = new Request();
request.get( url, function(err, resp, data) {
	if (err) throw err;
	
	var img = new Image();
	img.src = data;
	
	var canvas = new Canvas(256, 256);
	var ctx = canvas.getContext('2d');
	
	ctx.drawImage(img, 0, 0, 256, 256);
	canvas.createPNGStream().pipe(fs.createWriteStream('image-url.png'));
});

This should produce image-url.png in the current directory looking like this:

image-url

Good luck to you!

- Joe

@LinusU
Copy link
Collaborator

LinusU commented Aug 1, 2017

Also, this really should be supported directly by node-canvas to mimic how it's working in the browser. I'll try and add it to the 2.x release as soon as possible...

Something like this should work (although it doesn't at the moment)

const { createCanvas, loadImage } = require('canvas')
const canvas = createCanvas(200, 200)
const ctx = canvas.getContext('2d')

loadImage('http://placehold.it/256x256/0000ff/ffffff&text=node-canvas').then((image) => {
  ctx.drawImage(image, 50, 0, 70, 70)

  console.log('<img src="' + canvas.toDataURL() + '" />')
})

@latipun7
Copy link

latipun7 commented Aug 2, 2017

Following @jhuckaby method, I got this error.

Error: Image given has not completed loading

It seems because I call it in asynchronous function. How can I resolve this? I add await in front of request.get() still not working.


node-canvas version: 2.0.0-alpha.1

@jhuckaby
Copy link
Contributor

jhuckaby commented Aug 2, 2017

@RyuukiBeat Try using img.onload maybe? See https://github.com/Automattic/node-canvas/blob/master/examples/resize.js for example usage.

@geuis
Copy link

geuis commented Aug 7, 2017

The way I did this was to subclass the Image object. Note that I'm using restify in another part of my app, but that doesn't matter to this example:

const https = require('https');
const url = require('url');
const Canvas = require('canvas');
const restifyClients = require('restify-clients');

// sets a limit on simultaneous outbound connections to
// prevent overloading the api servers.
const agent = new https.Agent({
  maxSockets: 4
});

class Image extends Canvas.Image {
  constructor() {
    super();

    this.events = [];
    this.onload = () => {
      this.fireEvent('load');
      this.handlerCleanup();
    };
  }

  set src(val) {
    this.url = val;

    const uri = url.parse(val);
    const client = restifyClients.createHttpClient({
      url: `${uri.protocol}//${uri.host}/`
    });
    const opts = {
      path: uri.path,
      agent: agent,
      retry: {
        retries: 10
      }
    };

    client.get(opts, (err, req, res) => {
      if (err) {
        // connection error
        console.log('ImageConnectionError:', err);
        this.fireEvent('error', err);
        this.handlerCleanup();

        return;
      }

      req.on('result', (err, response) => {
        if (err) {
          this.fireEvent('error', err);
          this.handlerCleanup();

          return;
        }

        let buff = new Buffer.alloc(0);

        response.on('data', chunk => {
          buff = Buffer.concat([buff, chunk], buff.length + chunk.length);
        });

        response.on('end', () => {
//          console.log(this.url);
          super.src = buff;
        });

        response.on('error', err => {
          this.fireEvent('error', err);
          this.handlerCleanup();
        });
      });
    });
  }

  // limits memory leaks from node-canvas Image
  handlerCleanup() {
    delete this.onload;
    delete this.onerror;
  }

  addEventListener(event, cb) {
    this.events.push({
      type: event,
      fn: cb
    });
  }

  fireEvent(ev, data) {
    this.events.forEach(event => (event.type === ev ? event.fn(data) : null));
  }
}

module.exports = Image;

@zbjornson zbjornson changed the title i want add image with url? Support img.src = <url> Jun 17, 2018
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 1, 2018
Fixes Automattic#945 - support img.src = <url>
Fixes Automattic#807 - support for non-base64 `data:` URIs
Fixes Automattic#1079 - ditto
Closes Automattic#564 - it works, probably didn't pass a string or buffer

Makes all examples and the README use onload, onerror.
@zbjornson zbjornson mentioned this issue Jul 1, 2018
1 task
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 1, 2018
Fixes Automattic#945 - support img.src = <url>
Fixes Automattic#807 - support for non-base64 `data:` URIs
Fixes Automattic#1079 - ditto
Closes Automattic#564 - it works, probably didn't pass a string or buffer

Makes all examples and the README use onload, onerror.
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 2, 2018
Fixes Automattic#945 - support img.src = <url>
Fixes Automattic#807 - support for non-base64 `data:` URIs
Fixes Automattic#1079 - ditto
Closes Automattic#564 - it works, probably didn't pass a string or buffer

Makes all examples and the README use onload, onerror.
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 6, 2018
Fixes Automattic#945 - support img.src = <url>
Fixes Automattic#807 - support for non-base64 `data:` URIs
Fixes Automattic#1079 - ditto
Closes Automattic#564 - it works, probably didn't pass a string or buffer

Makes all examples and the README use onload, onerror.
zbjornson added a commit that referenced this issue Jul 6, 2018
* Clean up img.src=

Fixes #945 - support img.src = <url>
Fixes #807 - support for non-base64 `data:` URIs
Fixes #1079 - ditto
Closes #564 - it works, probably didn't pass a string or buffer

Makes all examples and the README use onload, onerror.

* image: throw if no onerror listener attached
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants