pdf2png.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* Copyright 2017 Mozilla Foundation
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. const Canvas = require("canvas");
  16. const assert = require("assert").strict;
  17. const fs = require("fs");
  18. function NodeCanvasFactory() {}
  19. NodeCanvasFactory.prototype = {
  20. create: function NodeCanvasFactory_create(width, height) {
  21. assert(width > 0 && height > 0, "Invalid canvas size");
  22. const canvas = Canvas.createCanvas(width, height);
  23. const context = canvas.getContext("2d");
  24. return {
  25. canvas,
  26. context,
  27. };
  28. },
  29. reset: function NodeCanvasFactory_reset(canvasAndContext, width, height) {
  30. assert(canvasAndContext.canvas, "Canvas is not specified");
  31. assert(width > 0 && height > 0, "Invalid canvas size");
  32. canvasAndContext.canvas.width = width;
  33. canvasAndContext.canvas.height = height;
  34. },
  35. destroy: function NodeCanvasFactory_destroy(canvasAndContext) {
  36. assert(canvasAndContext.canvas, "Canvas is not specified");
  37. // Zeroing the width and height cause Firefox to release graphics
  38. // resources immediately, which can greatly reduce memory consumption.
  39. canvasAndContext.canvas.width = 0;
  40. canvasAndContext.canvas.height = 0;
  41. canvasAndContext.canvas = null;
  42. canvasAndContext.context = null;
  43. },
  44. };
  45. const pdfjsLib = require("pdfjs-dist/legacy/build/pdf.js");
  46. // Some PDFs need external cmaps.
  47. const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
  48. const CMAP_PACKED = true;
  49. // Where the standard fonts are located.
  50. const STANDARD_FONT_DATA_URL =
  51. "../../../node_modules/pdfjs-dist/standard_fonts/";
  52. // Loading file from file system into typed array.
  53. const pdfPath =
  54. process.argv[2] || "../../../web/compressed.tracemonkey-pldi-09.pdf";
  55. const data = new Uint8Array(fs.readFileSync(pdfPath));
  56. // Load the PDF file.
  57. const loadingTask = pdfjsLib.getDocument({
  58. data,
  59. cMapUrl: CMAP_URL,
  60. cMapPacked: CMAP_PACKED,
  61. standardFontDataUrl: STANDARD_FONT_DATA_URL,
  62. });
  63. (async function () {
  64. try {
  65. const pdfDocument = await loadingTask.promise;
  66. console.log("# PDF document loaded.");
  67. // Get the first page.
  68. const page = await pdfDocument.getPage(1);
  69. // Render the page on a Node canvas with 100% scale.
  70. const viewport = page.getViewport({ scale: 1.0 });
  71. const canvasFactory = new NodeCanvasFactory();
  72. const canvasAndContext = canvasFactory.create(
  73. viewport.width,
  74. viewport.height
  75. );
  76. const renderContext = {
  77. canvasContext: canvasAndContext.context,
  78. viewport,
  79. canvasFactory,
  80. };
  81. const renderTask = page.render(renderContext);
  82. await renderTask.promise;
  83. // Convert the canvas to an image buffer.
  84. const image = canvasAndContext.canvas.toBuffer();
  85. fs.writeFile("output.png", image, function (error) {
  86. if (error) {
  87. console.error("Error: " + error);
  88. } else {
  89. console.log(
  90. "Finished converting first page of PDF file to a PNG image."
  91. );
  92. }
  93. });
  94. // Release page resources.
  95. page.cleanup();
  96. } catch (reason) {
  97. console.log(reason);
  98. }
  99. })();