zoukankan      html  css  js  c++  java
  • 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_ scrollWidth, full_height: scrollHeight, page_ 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

  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/lovelylife/p/4137287.html
Copyright © 2011-2022 走看看