Chrome瀏覽器網頁截全屏算法以及實現


做個一個簡單的批量下載插件叫“挖一下”, 正如插件的名字一樣,采集網頁里面的所有圖片,根據篩選條件過濾不需要的圖片,最后下載選中的圖片。

索性把網頁也一起給截了,截屏分兩種:

1.可見內容截屏

2.完整網頁截屏(包括可見和不可見)

 

可見內容截屏:

實現原理:直接通過chrome自帶的截屏方法(chrome.tabs.captureVisibleTab),回調函數返回圖片類型和數據信息

chrome.tabs.captureVisibleTab({format:'png'}, function(screenshotUrl) {
  // 保存screenshotUrl, image信息,默認使用png格式        
});

 

完整網頁截屏

實現原理:因為chrome本身沒有提供類似的截全屏的接口,或者不知道;於是找了很多方法,最終使用的方法就是自動滾動網頁,然后一屏一屏的截(還是chrome.tabs.captureVisibleTab),並將這些小的截屏數據保存到緩存,通過canvas來合並。步驟如下:

(1)根據當前網頁的scrollWidth和scrollHeight以及可視區域的clientWidth和clientHeight來計算最后需要截屏幾次, 將網頁整個網頁拆分成多個截屏數據塊。截屏代碼如下:

var scrollWidth = document.body.scrollWidth;
var scrollHeight = document.body.scrollHeight;
var visibleWidth = document.documentElement.clientWidth;
var visibleHeight = document.documentElement.clientHeight;
// 根據可視區域計算整個網頁可以拆分成多少行多少列 
var columns = Math.ceil(scrollWidth*1.0 / visibleWidth); 
var rows = Math.ceil(scrollHeight*1.0 / visibleHeight); 

var canvas_data = {
  size: {full_width: scrollWidth, full_height: scrollHeight, page_width: visibleWidth, page_height:visibleHeight},
  table:{rows: rows, colums: columns},
  screenshots: [] 
};

// 最后一行行的循環滾動頁面截屏 
for(var r=0; r<rows; r++) { 
  document.body.scrollHeight = r*visibleHeight; 
  for(var c=0; c<columns; c++) { 
    document.body.scrollLeft = c*visibleWidth; 
    // 截屏並保存 
    chrome.tabs.captureVisibleTab({format:'png'}, function(screenshotUrl) {
        canvas_data.screenshots.push({row: r, column: c, data_url: screenshotUrl});
    });
  } 
}

 

(2)通過canvas合並圖像。

截屏之后得到一個截屏數組,數組的每一個元素都帶有一個行號和列號,代表這個圖像是網頁的第幾行第幾列的圖小。

當前網頁的scrollWidth和scrollHeight創建一個canvas,根據元素信息以及以及可視區域的clientWidth和clientHeight,將圖片一張張畫到canvas。

function merge_images(canvas_data, image_element) {
  // initialize canvas
  var canvas = document.createElement("canvas");
  canvas.width = canvas.size.full_width;
  canvas.height = canvas.size.full_height;
  draw_image(canvas, canvas_data, 0, image_element);
}

function draw_image(canvas, canvas_data, n, image_element) {
  var screenshots = canvas_data.screenshots;
  if(n >= screenshots.length ) {
    // draw completed
    image_element.src = canvas.toDataURL('image/png');
  } else {
    console.log('draw '+n+' image');
    var draw_context = canvas.getContext("2d");
    var s = screenshots[n];
    var row = s.row;
    var column = s.column;
    var x=0, y=0;
    if(row < canvas_data.table.rows-1) {
      y = row*canvas_data.size.page_height;
    } else { // last row
      y = canvas.height - canvas_data.size.page_height; 
    }

    if(column < canvas_data.table.columns-1) {
      x = column*canvas_data.size.page_width;
    } else { // last column
      x = canvas.width - canvas_data.size.page_width; 
    }
    console.log('x:' + x + ', y=' + y); 
    var memory_image = new Image();
    memory_image.onload =  (function(ctx, m, l, t) { 
      return function() {
        console.log('image load ok');
        ctx.drawImage(m,l,t); 
        draw_image(canvas, canvas_data, ++n, image_element);
      }
    })(draw_context, memory_image, x, y);
    memory_image.src = s.data_url;
  }
}

當canvas畫圖結束后,用img元素顯示圖像,代碼如下:

image_element.src = canvas.toDataURL('image/png');

到此ok了,折騰好幾天了,

插件源碼地址:http://git.oschina.net/iknown/wayixia-chrome-extension

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM