经常在微博上看到很多内容使用的什么长微博截图,并且截图上还附加了很多其他的信息。之前对纯前端截图有些研究,正好本博客有这个需求,今天就把这东西实现了下。

需要声明的是,JavaScript 目前还不能实现网页截屏,就算以后能够实现,也一定是浏览器提供了相关接口,JS 去调用这些接口。既然不能截屏,那我们能做的只有通过拿到像素点的信息来”拼凑”图片。

先说说我们看到的截屏方式

用过 phantomJS 的同学都知道,它提供了一个截屏函数,通过它可以整屏获取页面截图,而且他支持的格式也比较多:JPG/PNG/GIF/PDF。通过简单的两句命令就可以把一个网页截取下来:

// render.js
var webPage = require('webpage');
var page = webPage.create(); page.viewportSize = { width: 1920, height: 1080 };
page.open("http://www.taobao.com", function start(status) {
page.render('taobao_home.jpeg', {format: 'jpeg', quality: '100'});
phantom.exit();
});

安装 phantomjs 之后执行下上面的文件:

phantomjs render.js

你会发现,一张宽度很窄的淘宝首页图就保存到了同目录下的 taobao_home.jpeg 中。也有同学使用 phantomjs 做了很多有意思的东西,比如每隔 100ms 截图,然后对比图像之间的差异,分析网页的加载情况和性能问题,甚至做网页的监控。好吧,话题收回来,继续说说其他的截屏方式,关于 phantomjs 可以移步到官网学习。

前端截屏方案

能够导出图片的,目前只有 canvas。页面上的元素,除了图片、视音频、SVG等,其他都是文字,都可以使用 css 样式变换出来。我们知道,在 canvas 中是可以绘制图片和文字的,那么问题就很好解决了。

  • 遍历页面的所有元素,提取DOM数
  • 获取渲染之后的每个 DOM 节点的内联、外链 CSS 属性
  • 将样式转换成 canvas 的属性,利用 offset 等属性辅助摆放位置,将节点对应到 canvas 上

这个方案比较粗糙,但是对于简单的页面,以上操作就能导出一张几乎与原状一模一样的图片。当然,我们想到的,也有人实现出来了,html2canvas 就是一个关注度很高的 js 截屏库,它考虑的内容会更多更全面。比如:

我博客左侧的微博小图标,hover 上去有一个微博分享,这里我就使用了这个库截取博客全文视图(考虑小屏手机,我把宽度设置成 480,比较窄),其实现是很简单的:

html2canvas(document.body).then(function(canvas) {
canvas.id = 'screenshotCanvas';
document.body.appendChild(canvas);
});

此时,页面的截图已经 append 到了 body 中。canvas 提供了导出图片的函数:

var can = documeng.getElementById("screenshotCanvas");
var imgDataURI = can.toDataURL('image/png');

我们也可以将到处的内容转化成一个 blob 流,这样就能直接通过 URI 地址来访问了。

原始需求是将图片分享出去

无论是 dataURI 还是还是 blob 流,他们都没办法当做一个 URL 在网络上访问,所以当我使用微博分享(附加图片分享)的时候,图片总是拿不到。

var shareUrl = "http://service.weibo.com/share/share.php?appkey=YOUR_APP_KEY&title="
+ title + "&url=" + url + "&searchPic=false&style=simple&pic="
+ picUrl;

这里的 picUrl 必须是一个 http 可请求到的地址,实在是无奈呀,在 coding.net 写了一个小应用,用来临时储存图片(10分钟之后删除上传图片),有需要的可以试用下:

JQuery 用户可以这样搞:

var fd = new FormData();
fd.append("img", imgBlob);
$.ajax({
type: "POST",
url: "http://tmpfile.coding.io/img",
dataType: 'json',
data: fd,
crossDomain: true,
processData: false,
contentType: false,
success: function(data){
if(data && data.path) {
console.log("http://tmpfile.coding.io/tmp" + data.path);
}
}
});

小结

只要能拿到原始图,之后的加工处理都是比较简单的。比如如何实现画框截取某个区域的图形,思路就是截取整图,记住鼠标按下和抬起的两个点,然后从整图中抠出来就搞定了。在 QQ 空间发表说说的地方有提供截屏工具,这是因为腾讯在电脑上安装了插件,并且提供了对应的 JS 接口,JS 是没有能力直接截屏的。

好吧,了解原理就好,人家有现成的库可以用,咱们不要动不动就造轮子,不好玩。

引用https://www.barretlee.com/blog/2015/09/24/screenshot-with-javascript/

使用 JavaScript 截屏的更多相关文章

  1. javascript实现当前页面截屏

    javascript实现当前页面截屏 一.前言 有客户要求能对用户当前页面进行指定区域截屏,类似qq截屏的实现效果.比如用户在处理工作的时候,将当前页面录入后的一些信息进行截图下载保存.但又不能安装任 ...

  2. Javascript网页截屏的方法

    最近我在研究开发一个火狐插件,具体的功能是将网页内容截屏并分享到微博上.目前基本功能已经实现,大家可以在 @程序师视野 里看到用这个截图插件分享的微博的效果. 之前我曾写过如何将canvas图形转换成 ...

  3. 利用PhantomJS进行网页截屏,完美解决截取高度的问题

    关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS ...

  4. PhantomJS linux系统下安装步骤及使用方法(网页截屏功能)

    PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种Web标准: DOM 处理, CSS 选择器, JSON, ...

  5. nodejs+phantomjs+七牛 实现截屏操作并上传七牛存储

    近来研究了下phantomjs,只是初涉,还谈不上深入研究,首先介绍下什么是phantomjs. 官网上的介绍是:”PhantomJS is a headless WebKit scriptable ...

  6. 让编辑器支持word的复制黏贴,支持截屏的黏贴

    chrome有很多人性化的API,比如拖拽, 比如图片可以转化为base64等: 比如知乎上面的回复中可以直接黏贴图片,  就不需要手动点击图片上传按钮, 选择图片, 确认上传等等: 知乎参考地址:打 ...

  7. html2canvaces用法,js截屏并且下载

    1.首先自己下载引入html2canvaces和jquery(我的demo路径是自己本地的) 2.点击截屏按钮后,跳出层的其他部分是取消保存,点击截取获得的图片区域,表示保存 <!DOCTYPE ...

  8. 利用PhantomJS进行网页截屏

    利用PhantomJS进行网页截屏 关于PhantomJS PhantomJS 是一个基于WebKit的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速,原生支持各种W ...

  9. js 利用canvas + flv.js实现视频流 截屏 、本地下载功能实现,兼容火狐,谷歌;canvas截屏跨域问题,无音频视频流加载不显示问题

    项目:物联网监控项目----后台视频流管理(前端实现视频截屏功能) 本文就不同视频源分情况展示: 1 本地视频(项目同目录视频)截屏(canvas.getContext("2d).drawI ...

随机推荐

  1. wepy开发小程序eslint报错error 'getApp' is not defined no-undef

    wepy开发小程序使用getApp().globalData保存全局数据很方便,但是会在控制台看到很多报错:“error 'getApp' is not defined no-undef”,这是esl ...

  2. CSS基础学习(二) 之 width min-width max-width属性

    width 1. 设置元素内容区(content area)的宽度. 2. 如果box-szing属性设置为border-box,width表示border area的宽度,如下图 min-width ...

  3. Jquery实现轮播效果图

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  4. WIN8外包公司—长年承接WIN8(surface)应用外包—北京动点飞扬软件

    WIN8外包公司—长年承接WIN8(surface)应用外包 一.我们长年专门承接WIN8外包.Surface外包. WPF 外包.HTML5外包.WindowsPhone 外包.Silverligh ...

  5. Family 科

    拉丁语 familia 目--> 总科-->科-->亚科(亚科的拉丁文分类滋味通常是-inae) [族] 属

  6. Katy Perry - E.T.

    作曲 : Katy Perry, Łukasz Gottwald, Max Martin, Joshua Coleman 作词 : Katy Perry, Łukasz Gottwald, Max M ...

  7. ionic3 双向数据绑定失效 脏值检测失效

    最近在使用ionic3过程中,使用了eval()方法进行字符串拼接成一个function使用 在eval()方法中,只能使用局部变量,全局变量无法使用,ionic3的this在eval中失效(unde ...

  8. java常用类介绍

    1 日期时间.Math.枚举 1.1 日期时间 计算机如何表示时间? GMT时间指格林尼治所在地的标准时间,也称为时间协调时(UTC),其他地区的时间都是相对于GMT时间的偏移. 北京位于东八区 = ...

  9. 自我学习成长系列之<<FirstHead设计模式>>

    第一章 设计模式入门 1.好词好句: 好的设计是可以应付改变. 2.驱动改变的因素:(a)客户需求不清晰,后期会一直变 (b)遇到坑爹的产品,自己不会全扔给程序员 (c)在开发过程中,产生一个新概念, ...

  10. 『TensorFlow』张量拼接_调整维度_切片

    1.tf.concat tf.concat的作用主要是将向量按指定维连起来,其余维度不变:而1.0版本以后,函数的用法变成: t1 = [[1, 2, 3], [4, 5, 6]] t2 = [[7, ...