I have a .PDF file of 85 pages that I would like to make available for viewing in my application.
I have considered converting that file to PNG pictures, that I could display inside a scrollView component.
The problem is that to have a correct visual quality, the converted .PNG files makes 8MB, while the original .PDF is about 3MB
(I used Image Magick, to convert the .PDF file into .PNG ones, with the command line convert -density 144 manual.pdf manual.png)
(I tried with .JPG images first, but the result is even worse)
Is there any way to view a .PDF file directly from within a Cocos Creator application?
Thanks for the suggestion, Boby, but I can’t do something like new ccui.WebView("my_pdf_file"); as there is no WebView in Cocos Creator API
(EDIT: I just checked cocos2d-js.js file, and its confirmed, there is no WebView support in it)
I’m not a JavaScript expert, so if someone could explain me (an example would be wonderfull ) how to ‘embed’ a .PDF file into my Cocos Creator application, using previously mentioned pdf.js or anything else, that would be very cool!!
Ok, I have almost solved my troubles, here is how:
I first tried to work with pdf.js and pdf.worker.js, which are the files we should use in normal cases, but there was too much problems:
I first had to work around Cocos Creator complaining about node-ensure.
Then there was an other problem involving PDFJS.workerSrc which I was able to initialise correctly when using the version played directly from Cocos Creator, but not with the version built
Solution for those troubles: just use file pdf.combined.js (which contain pdf.js and pdf.worker.js combined into one single file) which can be found on that repository: https://github.com/mozilla/pdfjs-dist
With this file, Cocos Creator does not ‘complain’ anymore, no need to change the source code to work around node-ensure problem, no need to setup PDFJS.workerSrc, it just work OOTB!
Now, I just need to unserstand rendering context stuff…I’ll create a new thread for that and will update this one once the solution will be 100% working fine.
Thanks to the help of Huabin (aka @pandamicro), I was able to solve my context rendering problem.
Here is an example code displaying the first page of a PDF file.
First, you need to add to Cocos Creator the script file pdf.combined.js (which contain pdf.js and pdf.worker.js combined into one single file) which can be found on that repository: https://github.com/mozilla/pdfjs-dist
(you need to create a ‘resources’ directory into assets and put the PDF file in it)
(pdfSprite is a cc.Sprite already added to current scene canvas)
cc.Class({
extends: cc.Component,
properties: {
// Sprite that will contain a rendered PDF page
pdfSprite: {
default: null,
type: cc.Sprite
},
(…)
},
//-------------------------------
onLoad: function () {
var self = this;
self.displayPDFPage('resources/document.pdf', 1);
},
//-------------------------------
displayPDFPage: function(filename, pageNumber) {
var self = this;
// Build an URL with specified document file
var url = cc.url.raw(filename);
// Get and open the PDF document
PDFJS.getDocument(url).then(function(pdfDocument) {
console.log('Document ' + url + ' contain ' + pdfDocument.numPages + ' page(s)');
// Render the requested page
pdfDocument.getPage(pageNumber).then(function(page) {
// Get PDF page width & height
var scale = 1;
var viewport = page.getViewport(scale);
// Create a canvas and get the corresponding 2d drawing context, in which the PDF page will be rendered
var PDFcanvas = document.createElement('Canvas');
PDFcanvas.width = viewport.width;
PDFcanvas.height = viewport.height;
var PDFcontext = PDFcanvas.getContext('2d');
var renderContext = {
canvasContext: PDFcontext,
viewport: viewport
};
// Render the PDF page with this context
page.render(renderContext).then(function() {
// Build a spriteFrame and use that context as texture source
var texture2d = new cc.Texture2D();
texture2d.initWithElement(PDFcanvas);
texture2d.handleLoadedTexture();
self.pdfSprite.spriteFrame = new cc.SpriteFrame(texture2d, cc.rect(0, 0, PDFcanvas.width, PDFcanvas.height));
// Adjust height of the sprite according to document aspect ratio
var ratio = PDFcanvas.height / PDFcanvas.width;
self.pdfSprite.node.height = self.pdfSprite.node.width * ratio;
}, function(failureReason) {
console.log('**!!** An error occured when rendering page ' + pageNumber + ' : ' + failureReason);
});
}, function(failureReason) {
console.log('**!!** An error occured when accessing page ' + pageNumber + ' : ' + failureReason);
});
}, function(failureReason) {
console.log('**!!** An error occured with PDF file ' + url + ' : ' + failureReason);
});
},
(...)
How do you manage to make it work in the built code? When you build it, the resources has bundled and the url resulted by url.raw does not work anymore for me.