背景:项目现场提出将一个html做的图形页面导出为一张图片的需求,在网上搜了一下,发现都不是很全面,所以综合了很多大神的帖子,自己再次封装,以适用项目需求。

所需js库:html2canvas.js(https://github.com/niklasvh/html2canvas); Export2Image.js(自己封装),其中new Export2Image(htmlDom,[opts]).export()是执行导出命令。opts = {width:400,height:400,type:"png",fname:"downloadName"}为可选参数。

注意:在使用过程中,发现一个问题,dom背景图片千万不能设置background-size:contain/conver,否则背景图片导不出来。

代码:

 /**
* Created by tengri on 2016-5-9.
*/ /**
* 导出类
* @param content 要导出的内容
* @constructor
*/
function Export2Image(content,opts){
this.exportObj = typeof(content) == "string" ? document.getElementById(content) : content;
if(!this.exportObj) throw new Error("导出内容对象只能传递ID和DOM对象");
this.opts = opts || {};
if(this.exportObj.nodeName !="CANVAS"){
this.exportType = "html2Image";
this.canvas = document.createElement("canvas");
this.canvas.style.display = "none";
//如果没有设置宽度和高度,实际是多大就导出多大
this.canvas.width = this.opts.width || this.exportObj.scrollWidth + 10;
this.canvas.height = this.opts.height || this.exportObj.scrollHeight + 10;
}else{
this.exportType = "canvas2Image";
this.canvas = this.exportObj;
}
if(this.opts.width && this.opts.height){
this.actualWidth = this.opts.width;
this.actualHeight = this.opts.height;
}
this.type = this.opts.type || "png";
this.fileName = (this.opts.name || new Date().getTime()) + "." + this.type;
this.init();
return this;
} /**
* 初始化
*/
Export2Image.prototype.init = function(){
this._fixType();
} Export2Image.prototype._encodeData = function(data){
if(!window.btoa) throw "btoa undefined";
var strDtata = "";
if(typeof(data) !="string"){
for(var i = 0 ; i < data.length;i++){
strDtata +=String.fromCharCode(data[i]);
}
}else{
strDtata = data;
}
return window.btoa(strDtata);
}; /**
* 根据配置生成固定大小图片
* @param width
* @param height
*/
Export2Image.prototype._scaleCanvas = function(width,height){
var w = this.canvas.width;
var h = this.canvas.height;
width = width || w;
height = height || h; var newCanvas = document.createElement("canvas");
newCanvas.width = width;
newCanvas.height = height;
var ctx = newCanvas.getContext("2d");
ctx.drawImage(this.canvas,0,0,w,h,0,0,width,height);
this.canvas = newCanvas;
}; /**
* 获取canvas的Dataurl
*/
Export2Image.prototype._getDataURL = function(){
return this.canvas.toDataURL(this.type);
};
/**
* 获取导出图片类型
* @private
*/
Export2Image.prototype._fixType = function(){
var type = this.type.toLocaleLowerCase().replace(/jpg/i,"jpeg");
var res = type.match(/png|jpeg|bmp|gif/)[0];
this.type = "image/" + res;
}; /**
* 获取数据
*/
Export2Image.prototype.getData = function(){
if(this.actualWidth && this.actualHeight){
this._scaleCanvas(this.actualWidth,this.actualHeight);
}
var strData = "";
if (/bmp/.test(this.type)) {
var data = this._getImageData();
strData = this._getBitmapImage(data);
} else {
strData = this._getDataURL();
}
return strData;
} /**
* 普通图片获取
* @private
*/
Export2Image.prototype._getImageData = function(){
var w = this.canvas.width, h = this.canvas.height;
return this.canvas.getContext('2d').getImageData(0, 0, w, h);
}; /**
* 位图获取
* @private
*/
Export2Image.prototype._getBitmapImage = function(oData){
var aHeader = []; var iWidth = oData.width;
var iHeight = oData.height; aHeader.push(0x42); // magic 1
aHeader.push(0x4D); var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); aHeader.push(0); // reserved
aHeader.push(0);
aHeader.push(0); // reserved
aHeader.push(0); aHeader.push(54); // dataoffset
aHeader.push(0);
aHeader.push(0);
aHeader.push(0); var aInfoHeader = [];
aInfoHeader.push(40); // info header size
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0); var iImageWidth = iWidth;
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); var iImageHeight = iHeight;
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); aInfoHeader.push(1); // num of planes
aInfoHeader.push(0); aInfoHeader.push(24); // num of bits per pixel
aInfoHeader.push(0); aInfoHeader.push(0); // compression = none
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0); var iDataSize = iWidth*iHeight*3;
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); for (var i=0;i<16;i++) {
aInfoHeader.push(0); // these bytes not used
} var iPadding = (4 - ((iWidth * 3) % 4)) % 4; var aImgData = oData.data; var strPixelData = "";
var y = iHeight;
do {
var iOffsetY = iWidth*(y-1)*4;
var strPixelRow = "";
for (var x=0;x<iWidth;x++) {
var iOffsetX = 4*x; strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+2]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+1]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX]);
}
for (var c=0;c<iPadding;c++) {
strPixelRow += String.fromCharCode(0);
}
strPixelData += strPixelRow;
} while (--y); var strEncoded = this._encodeData(aHeader.concat(aInfoHeader)) + this._encodeData(strPixelData); return this._makeDataURI(strEncoded);
}; Export2Image.prototype._makeDataURI = function(strData){
return "data:" + this.type + ";base64," + strData;
} /**
* 保存
* @param data
* @param fileName
* @private
*/
Export2Image.prototype._saveFile = function(data,fileName){
try{
//TODO:IE浏览器
new ActiveXObject("Microsoft.XMLHTTP");
var oImg = document.createElement("img");
oImg.src = data;
oImg.onload = function(){
myWindow=window.open('','_blank','width=800,height=600');
myWindow.document.write("<img src='"+data+"'>")
myWindow.focus()
}
}catch(e){
var saveLink = document.createElementNS("http://www.w3.org/1999/xhtml","a");
saveLink.href = data;
saveLink.download = fileName;
var event = document.createEvent("MouseEvents");
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
saveLink.dispatchEvent(event);
} }; Export2Image.prototype.exportPic = function(){
if(this.exportType == "html2Image"){
if(typeof(html2canvas) !="function"){
alert("需要引入html2canvas.js库文件");
return;
}
var that = this;
html2canvas(this.exportObj, {
onrendered: function(canvas) {
that.canvas = canvas;
var data = that.getData();
var imgData = data.replace(that.type,'image/octet-stream');
that._saveFile(imgData,that.fileName);
}
});
}else{
var data = this.getData();
var imgData = data.replace(this.type,'image/octet-stream');
this._saveFile(imgData,this.fileName);
} };
 <html>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta charset="utf-8">
<head>
<title>dom页面导出为图片</title>
<style type="text/css">
#wrap{
width:400px;
height:300px;
line-height:300px;
font-family: "Courier New", Courier, monospace;
font-size: 18px;
text-align: center;
border: 1px solid #ccc;
background-image: url("img/a.jpg");
overflow: auto;
} </style>
</head>
<body>
<div id="wrap">这是DOM元素,相当于项目中的图形所在的div
</div>
<input type="button" value="html导出图片" onclick="htmlExportHandler();"/><br><hr/>
<canvas id="myCanvas" width="600" height="400" style="background:yellowgreen"></canvas>
<input type="button" value="canvas导出图片" onclick="canvasExportHandler();"/><br><hr/> </body>
</html>
<script type="text/javascript" src="js/html5.js"></script>
<script type="text/javascript" src="js/html2canvas.js"></script>
<script type="text/javascript" src="js/Export2Image.js"></script>
<script> window.onload = function() {
var canvas = document.getElementById("myCanvas");
var ctx=canvas.getContext('2d');
ctx.fillStyle='#FF0000';
ctx.fillRect(10,10,200,100); }; function htmlExportHandler(){
var oContent = document.getElementById("wrap");
new Export2Image(oContent,{type:"bmp",name:"html导出文件"}).export();
} function canvasExportHandler(){
new Export2Image("myCanvas").export();
} </script>                                                                                                                          

html页面、canvas导出图片的更多相关文章

  1. 利用canvas 导出图片

    1.使用canvas绘制图片,并将图片导出. 在本地直接访问静态网页时,无法使用toDataURL(),需要将网页发布后,canvas才能使用toDataURL获取画布上的内容.因为canvas不允许 ...

  2. 微信小程序 canvas导出图片模糊

    //保存到手机相册save:function () { wx.canvasToTempFilePath({ x: , y: , width: , //导出图片的宽 height: , //导出图片的高 ...

  3. canvas导出图片方法总结

    html代码 <canvas id="canvas" width="100" height="100" ></canvas ...

  4. php保存canvas导出的base64图片

    代码如下: <?php $img='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAABxCAYAAABoUdWRAAAAAXNSR0IAr ...

  5. canvas画布导出图片并下载

    近期在学习关于画布知识,关于 画布导出图片, 在导出jpeg格式的图片时,会发现图片背景色变成了黑色,原因是画布透明的地方 默认转成了黑色,可以在绘制画布前设置透明处背景色为白色. // 背景色转换成 ...

  6. JN_0011:改变PPT的页面尺寸,并导出图片

    1,改变尺寸 设计 --  幻灯片大小 --  自定义大小 2,导出图片 另存为 JPG 图片

  7. Activiti开发案例之activiti-app工作流导出图片

    前言 自从 Activiti 和 JBPM4 分家以后,Activiti 目前已经发展到了版本7,本着稳定性原则我们最终选择了6,之前还有一个版本5. 问题 在开发使用的过程中发现 Activiti ...

  8. html导出图片

    有一个神奇的库:html2canvas. 这个库简洁优美,使用方便. 下面先看一个小demo,它需要用到一张图片:haha.jpg. <html> <head> <scr ...

  9. vue组件:canvas实现图片涂鸦功能

    方案背景 需求 需要对图片进行标注,导出图片. 需要标注N多图片最后同时保存. 需要根据多边形区域数据(区域.颜色.名称)标注. 对应方案 用canvas实现涂鸦.圆形.矩形的绘制,最终生成图片bas ...

随机推荐

  1. 浅谈Java三大框架与应用

    前言:对于一个程序员来说,尤其是在java web端开发的程序员,三大框架:Struts+Hibernate+Spring是必须要掌握熟透的,因此,下面谈谈java三大框架的基本概念和原理. JAVA ...

  2. PAT_A1021#Deepest Root

    Source: PAT A1021 Deepest Root (25 分) Description: A graph which is connected and acyclic can be con ...

  3. Linux基础:find命令总结

    本文只总结一些常用的用法,更详细的说明见man find和 info find. find命令 find命令常用来查找文件或目录,可以根据给定的路径和表达式查找所需的文件或目录.该工具是由findut ...

  4. 进程(day09)

    进程的管理 一.进程的基础 进程和程序的区别 每个进程有自己的pid.PCB 操作系统上运行的所有进程构成一颗树. 如何查看这颗树? pstree() 树根进程是init pid是 进程间的亲缘关系两 ...

  5. [51Nod 1218] 最长递增子序列 V2 (LIS)

    传送门 Description 数组A包含N个整数.设S为A的子序列且S中的元素是递增的,则S为A的递增子序列.如果S的长度是所有递增子序列中最长的,则称S为A的最长递增子序列(LIS).A的LIS可 ...

  6. Oracle 解决表死锁

    select 'alter system kill session ''' || SID || ',' || SERIAL# || ''';' from ( select distinct a.sid ...

  7. Linux思维导图之用户、组和权限

    安全3A: Authenticanion认证:验证用户身份; 授权授权;依据身份进行不同权利的分配.Acouting | 劲舞团审计:监督工作. user:id -u 令牌:(护符)ID号 .Linu ...

  8. 常用rides命令

    rides使用步骤 1.源代码构建安装 1.下载,Linux下命令wget http://redis.io/download下载redis的包 2.解归档Linux下命令tar -xvf redis- ...

  9. Golang - 开篇必须吹牛逼

    目录 Golang - 开篇必须吹牛逼 Go牛逼吗 安装环境 Golang - 开篇必须吹牛逼 (1)我们为什么要学 高并发 深度 || 广度 (2)go学习思路和目标 多打多练 掌握go语言 做一个 ...

  10. Bootstrap关于表单(一)

    1.基础表单 表单中常见的元素主要包括:文本输入框.下拉选择框.单选按钮.复选按钮.文本域和按钮等. 在Bootstrap框架中,通过定制了一个类名`form-control`,也就是说,如果这几个元 ...