【问题标题】:Turn pdf into array of png's using javascript (with pdf.js)使用javascript(使用pdf.js)将pdf转换为png数组
【发布时间】:2020-10-25 21:26:45
【问题描述】:

我正在尝试开发一个前端代码,要求用户提供一个 pdf,然后在内部(在用户浏览器中)生成一个 png 数组(通过数据到 url),其中数组中的每个条目对应于pdf:

dat[0] = 第 1 页的 png
dat[1] = 第 2 页的 png
...

当我测试下面的代码时,页面以某种方式呈现在彼此之上并旋转。

<script src="http://cdnjs.cloudflare.com/ajax/libs/processing.js/1.4.1/processing-api.min.js"></script><html>
<!--
  Created using jsbin.com
  Source can be edited via http://jsbin.com/pdfjs-helloworld-v2/8598/edit
-->
<body>
  <canvas id="the-canvas" style="border:1px solid black"></canvas>
  <input id='pdf' type='file'/>

  <!-- Use latest PDF.js build from Github -->

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
  <script src="pdf.js"></script>
  <script src="pdf.worker.js"></script>
  <script type="text/javascript">
    //
    // Asynchronous download PDF as an ArrayBuffer
    //
    dat = [];
    

    var pdf = document.getElementById('pdf');
    pdf.onchange = function(ev) {
      if (file = document.getElementById('pdf').files[0]) {
        fileReader = new FileReader();
        fileReader.onload = function(ev) {
          //console.log(ev);
          PDFJS.getDocument(fileReader.result).then(function getPdfHelloWorld(pdf) {
            //
            // Fetch the first page
            //
            number_of_pages = pdf.numPages;

            for(i = 1; i < number_of_pages+1; ++i) {
              pdf.getPage(i).then(function getPageHelloWorld(page) {

              var scale = 1;
              var viewport = page.getViewport(scale);

              //
              // Prepare canvas using PDF page dimensions
              //
              var canvas = document.getElementById('the-canvas');
              var context = canvas.getContext('2d');
              canvas.height = viewport.height;
              canvas.width = viewport.width;

              //
              // Render PDF page into canvas context
              //
              var renderContext = {
                canvasContext: context,
                viewport: viewport};
              page.render(renderContext).then(function() {
                dat.push(canvas.toDataURL('image/png'));
              });
              });
            }
            //console.log(pdf.numPages);
            //console.log(pdf)

          }, function(error){
            console.log(error);
          });
        };
        fileReader.readAsArrayBuffer(file);
      }
    }

  </script>


<style id="jsbin-css">

</style>
<script>

</script>
</body>
</html>

我只对数组 dat 感兴趣。当我渲染数组中的图像时,我看到了 dat[0] = 第 1 页的 png(正确)
dat[1] = 第 1 页的 png 和第 2 页的 png 在彼此顶部旋转 180
...

如何确保在数组的每个条目中正确呈现单个页面?

【问题讨论】:

    标签: javascript pdf frontend png pdf.js


    【解决方案1】:

    尝试在不同的画布上渲染页面。您可以创建一个canvas 并将其附加到容器中使用

    var canvasdiv = document.getElementById('canvas');      
    var canvas = document.createElement('canvas');
    canvasdiv.appendChild(canvas);
    

    var url = 'https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf';
    
    var PDFJS = window['pdfjs-dist/build/pdf'];
    
    PDFJS.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
    
    var loadingTask = PDFJS.getDocument(url);
    
    loadingTask.promise.then(function(pdf) {
    
      var canvasdiv = document.getElementById('canvas');
      var totalPages = pdf.numPages
      var data = [];
    
      for (let pageNumber = 1; pageNumber <= totalPages; pageNumber++) {
        pdf.getPage(pageNumber).then(function(page) {
    
          var scale = 1.5;
          var viewport = page.getViewport({ scale: scale });
    
          var canvas = document.createElement('canvas');
          canvasdiv.appendChild(canvas);
    
          // Prepare canvas using PDF page dimensions
          var context = canvas.getContext('2d');
          canvas.height = viewport.height;
          canvas.width = viewport.width;
    
          // Render PDF page into canvas context
          var renderContext = { canvasContext: context, viewport: viewport };
    
          var renderTask = page.render(renderContext);
          renderTask.promise.then(function() {
            data.push(canvas.toDataURL('image/png'))
            console.log(data.length + ' page(s) loaded in data')
          });
        });
      }
    
    }, function(reason) {
      // PDF loading error
      console.error(reason);
    });
    canvas {
      border: 1px solid black;
      margin: 5px;
      width: 25%;
    }
    <script src="//mozilla.github.io/pdf.js/build/pdf.js"></script>
    
    <div id="canvas"></div>

    【讨论】:

      【解决方案2】:

      对于那些从谷歌来到这里寻求 Angular 解决方案的人来说,这里有一个实现,将每个页面呈现在不同的画布上。

      pdf-viewer.component.html

      <div *ngFor="let page of pages>
       <canvas #canvas hidden ></canvas>
       <img [src]="page">
      </div>
      

      pdf-viewer.component.ts

      import * as pdfjsLib from 'pdfjs-dist';
      pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
      
      @Component({
          selector: 'app-pdf-viewer',
          templateUrl: './pdf-viewer.component.html',
          styleUrls: ['./pdf-viewer.component.scss'],
      })
      export class PdfViewerComponent implements OnInit {
          constructor() { }
          @ViewChildren('canvas') canvas: QueryList<ElementRef<HTMLCanvasElement>>;
      
          @Input() pdfBase64: string;
      
          pages: string[] = [];
      
          ngOnInit(): void {
              this.setPages();
          }
      
          async setPages(): Promise<void> {
              const pdfDoc = await pdfjsLib.getDocument({ url: this.pdfBase64 }).promise;
              const totalPages = pdfDoc.numPages;
              this.pages = new Array(totalPages);
      
              for (let i = 0; i < totalPages; i++) {
                  pdfDoc.getPage(i + 1).then((page) => {
                      const canvas = this.canvas.toArray()[page.pageIndex].nativeElement;
      
                      this.renderPdfPageToCanvas(page, canvas).then(() => {
                          this.pages[page.pageIndex] = canvas.toDataURL('image/png');
                      });
                  });
              }
          }
      
          renderPdfPageToCanvas(page: pdfjsLib.PDFPageProxy, canvas: HTMLCanvasElement): pdfjsLib.PDFPromise<pdfjsLib.PDFPageProxy> {
              const viewport = page.getViewport({ scale: 1.0 });
              const height = viewport.height;
              const width = viewport.width;
              canvas.height = height;
              canvas.width = width;
              const renderContext = {
                  canvasContext: canvas.getContext('2d'),
                  viewport: viewport
              };
              return page.render(renderContext).promise;
          }
      }
      
      

      package.json

      {
          ...
          "dependencies": {
              ...
              "@angular/core": "^9.1.11",
              "pdfjs-dist": "2.3.200"
          },
          "devDependencies": {
              ...
              "@types/pdfjs-dist": "2.1.3"
          }
      }
      
      

      【讨论】:

        猜你喜欢
        • 2013-05-23
        • 2014-04-07
        • 2018-01-08
        • 2013-12-27
        • 2011-02-21
        • 2011-06-27
        • 1970-01-01
        • 1970-01-01
        • 2019-10-24
        相关资源
        最近更新 更多