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

  • 相关阅读:
    java程序后台报错java.net.SocketException: Too many open files
    linux中,查看某个命令是来自哪个RPM包或者是通过哪个RPM包安装的
    Oracle卸载之linux快速卸载rac脚本-一键卸载
    40个DBA日常维护的SQL脚本
    Oracle SQL开发 之 Select语句完整的执行顺序
    Oracle开发 之 主-外键约束FK及约束的修改
    drop user 报错ora-00604
    oracle Bug 4287115(ora-12083)
    Ora-1157 ora-1110错误解决案例一枚
    rac库grid目录权限(6751)导致数据库宕机案例 此方法仅用于紧急救助
  • 原文地址:https://www.cnblogs.com/lovelylife/p/4137287.html
Copyright © 2011-2022 走看看