Unknown image format error when adding PNG ArrayBuffer
See original GitHub issueI’m using the prebuilt version of PDFKit in the browser, and when attempting to add a PNG I get the following error:
Uncaught Error: Unknown image
PDFImage.open format.util.js:546
module.exports.image deflate.js:773
img.onload PDFrenderer.js:195
I’m converting my images to PNG on the server (to crop them into circles) and the mime type of the images returned by the server is ‘image/png’. I’m unsure whether the method I’m using to convert the PNG into an ArrayBuffer is incorrect.
Here is the code I use to fetch the PNG and convert it into an ArrayBuffer:
var img = new Image, ctxData;
img.onError = function () {
throw new Error('Cannot load image: "' + url + '"');
}
img.onload = function () {
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
ctxData = canvas.toDataURL('image/png').slice('data:image/png;base64,'.length);
ctxData = atob(ctxData);
document.body.removeChild(canvas);
var buffer = [];
for (var i = 0, l = ctxData.length; i < l; i++) {
buffer.push(ctxData.charCodeAt(i));
buffer._isBuffer = true;
buffer.readUInt16BE = function (offset, noAssert) {
var len = this.length;
if (offset >= len) return;
var val = this[offset] << 8;
if (offset + 1 < len)
val |= this[offset + 1];
return val;
}
}
pdf.image(buffer);
}
img.src = url;
This works fine for JPEGs when this line is changed from
ctxData = canvas.toDataURL('image/png').slice('data:image/png;base64,'.length);
to
ctxData = canvas.toDataURL('image/jpeg').slice('data:image/jpeg;base64,'.length);
however I need to be able to pass in PNGs so that I can place I can place round images over any background.
I’ve also tried passing in the full url (e.g. ‘http://mysite.dev/userimages/1234/roundavatar.png’), however I’m then presented with the following error:
Uncaught TypeError: undefined is not a function
PDFImage.open util.js:535
module.exports.image deflate.js:773
Hope this is just something I’ve been doing wrong, and thanks for the great library!
Issue Analytics
- State:
- Created 9 years ago
- Comments:14 (1 by maintainers)
Top GitHub Comments
@Janneman84 I’m using promises, so once they resolve I call
doc.image
using theresponse's ArrayBuffer data
. Without the second fix I mentioned, the first image added withdoc.image
is used for all calls todoc.image
. I’ll see if I can reproduce it and post the code when I get off work.Here is how I am using the response data:
@Janneman84 Thanks, I used your workaround to be able to embed
PNGs
on the browser! I’m not 100% sure what I am about to say is related to this, but I couldn’t find a ticket about it so I will go ahead and mention. If I try to embed multiple images withdoc.image()
, it always uses the first one. I think this has to do with the way it pulls from imageRegistry whenisBuffer
returnsfalse
.Edit: To fix the issue, I removed the following check from
line 3945
:I think this essentially removes any caching capabilities. @devongovett , would this have any other side effects? Is there a way you think this should be fixed for us browser users? I’d be happy to work on a PR.