Skip to content

Missing sync canvas.toDataURL("image/jpeg") API #1146

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

Closed
challakoushik opened this issue Apr 18, 2018 · 7 comments · Fixed by #1194
Closed

Missing sync canvas.toDataURL("image/jpeg") API #1146

challakoushik opened this issue Apr 18, 2018 · 7 comments · Fixed by #1194
Assignees
Labels

Comments

@challakoushik
Copy link

I am using jsdom and node-canvas to run frontend html canvas code within node js, one of my script files has the line
canvas.toDataURL('image/jpeg',{quality:1},function(){})

the third parameter is because node-canvas demands 3 parameters over here at line 301 in canvas.js

else if ('image/jpeg' === type) {
    if (undefined === fn) {
      throw new Error('Missing required callback function for format "image/jpeg"');
    }

    var stream = this.jpegStream(opts);
    // note that jpegStream is synchronous
    var buffers = [];
    stream.on('data', function (chunk) {
      buffers.push(chunk);
    });
    stream.on('error', function (err) {
      fn(err);
    });
    stream.on('end', function() {
      var result = 'data:image/jpeg;base64,' + Buffer.concat(buffers).toString('base64');
      fn(null, result);
    });
  }

but jsdom passes only two arguments to this, and it might not be their fault since the official frontend canvas.toDataURL is supposed to take only 2 arguments.
I need to generate pdfs using jpg images generated by canvas in node. Would appreciate any help

@zbjornson zbjornson added the Bug label Apr 19, 2018
@zbjornson
Copy link
Collaborator

You're right, "image/jpeg" currently only has async support, and the async API is non-standard.

Until that's fixed, you could use canvas.jpegStream() to create your JPEG buffers (in the same way that's done in the code that you pasted).

@zbjornson zbjornson changed the title Why is Canvas.toDataURL forcing me to give 3 arguments. Need Help!! Missing sync canvas.toDataURL("image/jpeg") API Apr 19, 2018
@challakoushik
Copy link
Author

challakoushik commented Apr 19, 2018

@zbjornson , yes, but again the canvas on which I'm using toDataURL() is an htmlcanvas element, which goes through jsdom and then goes to node canvas, and jsdom does not have jpegStream()

so is there a way i can create a node-canvas object using a html canvas element. If so, that would solve the issue

@zbjornson
Copy link
Collaborator

Sorry -- I meant you could do that by accessing the node-canvas Canvas instance that jsdom wraps, which I think is just canvas._getCanvas().

They actually provide their own implementation of toBlob that supports image/jpeg that you might be able to use: https://github.com/jsdom/jsdom/blob/2e90c57c282eb06023fab09304e29622268b91cb/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js#L62-L86

@challakoushik
Copy link
Author

@zbjornson the _getCanvas does not exist in my HTMLCanvasElement, this method belongs to the HTMLCanvasElementImpl class as in HTMLCanvasElementImpl.js. I am unable to find the HTMLCanvasElementImpl instance in my HTMLCanvasElement

@zbjornson
Copy link
Collaborator

My bad. Looks like you'd have to use the method described here to get to the canvas instance: jsdom/jsdom#2067.

@challakoushik
Copy link
Author

challakoushik commented Apr 19, 2018

The toBlob method worked. The code below did the job for me

canvas.toBlob(function(result){
    var buffer = result[Object.getOwnPropertySymbols(result)[0]]._buffer;
    fs.writeFileSync('images/temp.jpg',buffer)
},'image/jpeg',1)

Thanks for helping me out!!
but I had a minor concern in line 71 of https://github.com/jsdom/jsdom/blob/2e90c57c282eb06023fab09304e29622268b91cb/lib/jsdom/living/nodes/HTMLCanvasElement-impl.js#L62-L86
isn't Math.min(0, Math.max(1, qualityArgument)) * 100 always supposed to return 0? haha!
The image generated looks fine I'm not sure if its of max quality now because of that line.

PS: I submitted an issue in jsdom jsdom/jsdom#2200

@zbjornson
Copy link
Collaborator

Glad that worked.

That does look wrong :) -- you could open an issue with jsdom for that.

@zbjornson zbjornson self-assigned this Apr 20, 2018
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 2, 2018
Also fixes a bug I introduced in Automattic#1152 (JPEG quality needs to go from 0 to 1, not 0 to 100).

Fixes Automattic#1146
zbjornson added a commit to zbjornson/node-canvas that referenced this issue Jul 2, 2018
Also fixes a bug I introduced in Automattic#1152 (JPEG quality needs to go from 0 to 1, not 0 to 100).

Fixes Automattic#1146
chearon pushed a commit that referenced this issue Jul 5, 2018
Also fixes a bug I introduced in #1152 (JPEG quality needs to go from 0 to 1, not 0 to 100).

Fixes #1146
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants