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

需要声明的是,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. kvm键盘使用

    在新建导向的时候最后一步之前,选择查看细节那里,在desplay的地方选择VNC server ,再在keyboard地方选择us-en,这下进入安装界面就可以了.

  2. FL studio的循环模式简介

    在FL studio中,有一个非常有用的功能,它可以加快我们的工作进程,它就是循环模式. 通过频道循环,我们可以在单个模式中创建整个项目,然后使用“按频道分割”将它们分开,以便在播放列表中排列.通常情 ...

  3. linux驱动编写(pwm驱动)【转】

    本文转载自:https://blog.csdn.net/feixiaoxing/article/details/79889240 pwm方波可以用来控制很多的设备,比如它可以被用来控制电机.简单来说, ...

  4. Java项目中使用log记录日志的一些总结

    本文介绍了一下自己在Java项目中使用log的一些总结,从日志的作用.日志的选用.日志级别介绍.日志记录的一些最佳实践几个方面阐述. 日志的作用 主要作用包括: 1.出问题后定位当时问题 2.显示程序 ...

  5. backbone点滴

    可以查看http://www.css88.com/doc/backbone/ backbone与angular http://www.infoq.com/cn/articles/backbone-vs ...

  6. less点滴

    1.简单的嵌套: less中显示: css中显示 2.作为值的变量: less中: @green: #801f77;@baise:white; header,footer{ background: @ ...

  7. windows server2008 IIS搭建网站简易教程(阿里云)

    最近搞了个阿里云服务器 想着需要用这个服务器学点东西,故而想着把自己之前写的网站能部署上去,虽然自己是做前端移动开发,但是对这个服务器的东西也很感兴趣 第一步 配置阿里云入口规则 如图开放81 80 ...

  8. git项目远程地址修改后本地如何处理

    今天运维人员为了方便管理,将远程的项目地址给迁移了, 原来是 git@git.lalala.com:yuanlaide/happy.git 变成了 git@git.lalala.com:houlaid ...

  9. SWUST OJ(957)

    逆置单链表 #include <stdio.h> #include <stdlib.h> typedef struct LNode { char data; struct LN ...

  10. 『TensorFlow』读书笔记_TFRecord学习

    一.程序介绍 1.包导入 # Author : Hellcat # Time : 17-12-29 import os import numpy as np np.set_printoptions(t ...