移動端提高pdf預覽清晰度

背景:

移動端預覽PDF文件,通用的解決方案是使用vue-pdf插件,其內置pdf.js,原理是基於 HTML5 的 <pdf> 標籤,通過將 PDF 文件轉換爲圖片或<canvas>來實現對 PDF 文件的預覽,插件好使沒毛病😆,但是如果我們的需求是要在移動端預覽內容很密集的文件時,預覽效果就不理想了,比如這樣:





 

針對此需求場景,我們需要解決兩個問題,一是提高pdf預覽文件的清晰度二是支持放大拖動查看

提高預覽文件清晰度的方法:

//1 優先放大scale的參數,一般把1變爲2,如果不夠可以繼續變大;
//2 在build/pdf.js文件,尋找DEFAULT_RANGE_CHUNK_SIZE配置項,並修改爲65536*16
//3 對canvas畫布,進行縮放,修改devicePixelRation這個參數,將它擴大

上述是谷歌給的解決方法,具體代碼如下:

<template>
    <div class="pdf" ref="pdfContent" id="your-iframe-id" v-if="pdfUrl">
        <pdf    
            v-for="i in numPages"
            :key="i"
             ref="wrapper" 
             :src="pdfUrl"
             :page="i"
         ></pdf>
    </div>
</template>
<script>
//...
支持手勢放大 canScale
 import pdf from "vue-pdf";
 export default {
 components: { pdf },
 data() {
  return {
     canScale: "width=device-width,initial-scale=1,maximum-scale=10,user-scalable=yes,viewport-fit=cover",
  };
 },
 created() {
    let viewport = document.querySelector("meta[name=viewport]");
    viewport.setAttribute("content", this.canScale) 
    let _this = this;
    let loadingTask = pdf.createLoadingTask(pdfUrl);
    loadingTask.then((pdf) => {
       _this.pdfUrl = loadingTask;
       _this.numPages = pdf.numPages;
    })
     .catch((err) => {
        console.error(err, "pdf加載失敗");
      });
  },
};
//...
 </script>

//修改build/pdf.js文件
/Users/jiaolongchao/Documents/work/ins-pdf-prd/node_modules/pdfjs-dist/build/pdf.js
 var DEFAULT_RANGE_CHUNK_SIZE = 65536*16;





 

通過上述操作,可以發現效果不是很明顯,scale越大,pdf中的字體越細,銳度越高,但是清晰度依舊不理想,如果在pc端,展示的位置足夠大,可以很大的程度上解決不夠清楚的問題。





 

pc端的預覽效果,提醒我們可以修改devicePixelRation這個參數,window.devicePixelRatio 是一個瀏覽器窗口對象的屬性,它表示設備物理像素和設備獨立像素的比例。這個比例反映了顯示設備上每個物理像素由多少個獨立像素組成的程度,它的作用就是可以高分辨率顯示支持圖像優化,它的值會隨着設備和瀏覽器的不同而變化。

// ... /Users/jiaolongchao/Documents/work/ins-pdf-prd/node_modules/vue-pdf/src/pdfjsWrapper.js 
this.renderPage = function(roate) { 
    //...  
    rotate = (pdfPage.rotate === undefined ? 0 : pdfPage.rotate) + (rotate === undefined ? 0 : rotate); 
    var scale = canvasElt.offsetWidth / pdfPage.getViewport(1).width * (window.devicePixelRatio || 1); 
    //根據實際情況擴大window.devicePixelRatio 
    var viewport = pdfPage.getViewport(scale, rotate); 
    emitEvent('page-size', viewport.width, viewport.height); 
    canvasElt.width = viewport.width; canvasElt.height = viewport.height; } 
..//





 

此時預覽的文件已經可以清晰的查看了👏👏👏,但是問題又來了,我們修改的是node_modules的源碼,爲了不影響其它項目對基礎庫的依賴,patch-package 提供了一種在不修改源代碼的情況下,對模塊進行熱修補的方法,可以完美解決這個問題;

具體來說,patch-package的工作原理是:

安裝patch-package,在項目目錄下運行 npm install patch-package命令,安裝該模塊,創建布丁文件,在需要修改的模塊的文件夾下創建一個 .patch 文件,並將需要修改的代碼寫入該文件中。

應用補丁:在項目根目錄下運行 patch-package 命令,將創建的補丁文件應用到目標模塊中。

通過這種方式,patch-package 可以在不修改源代碼的情況下,對模塊進行熱修補,從而避免了依賴關係混亂和無法正常運行的問題。同時,由於補丁文件可以隨時創建和修改,因此也可以隨時進行熱修補,非常方便。




在h5頁面中放開手勢縮放限制,顯的有些美中不足,可以通過修改面板大小來支持彈窗區域內的放大查看,通過動態修改ref值的transform 值,來支持成倍的放大和縮小,在交互上更和合理友好一些,這裏要注意,不能使用style的width控制,canvas面板會神奇消失;😢

computed: {
 scaleFun: function() {
   var scale = this.scale;
   return `transform:scale(${scale}); transform-origin:left top`;
  },
 },
//...
 scaleD() {
   this.scale += 1;
   console.log("放大", this.scale);
  },
 //縮小
scaleX() {
 if (this.scale == 1) {
   return;
 }
  this.scale += -1;
 },

經過這一系列的優化動作,在移動端就可以很清晰的預覽pdf文件了;





 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章