zoukankan      html  css  js  c++  java
  • html页面、canvas导出图片

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

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

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

    代码:

      1 /**
      2  * Created by tengri on 2016-5-9.
      3  */
      4 
      5 /**
      6  * 导出类
      7  * @param content  要导出的内容
      8  * @constructor
      9  */
     10 function Export2Image(content,opts){
     11     this.exportObj = typeof(content) == "string" ? document.getElementById(content) : content;
     12     if(!this.exportObj) throw new Error("导出内容对象只能传递ID和DOM对象");
     13     this.opts = opts || {};
     14     if(this.exportObj.nodeName !="CANVAS"){
     15         this.exportType = "html2Image";
     16         this.canvas = document.createElement("canvas");
     17         this.canvas.style.display = "none";
     18         //如果没有设置宽度和高度,实际是多大就导出多大
     19         this.canvas.width = this.opts.width || this.exportObj.scrollWidth + 10;
     20         this.canvas.height = this.opts.height || this.exportObj.scrollHeight + 10;
     21     }else{
     22         this.exportType = "canvas2Image";
     23         this.canvas = this.exportObj;
     24     }
     25     if(this.opts.width && this.opts.height){
     26         this.actualWidth = this.opts.width;
     27         this.actualHeight = this.opts.height;
     28     }
     29     this.type =  this.opts.type || "png";
     30     this.fileName = (this.opts.name || new Date().getTime()) + "." + this.type;
     31     this.init();
     32     return this;
     33 }
     34 
     35 /**
     36  * 初始化
     37  */
     38 Export2Image.prototype.init = function(){
     39     this._fixType();
     40 }
     41 
     42 Export2Image.prototype._encodeData = function(data){
     43     if(!window.btoa) throw "btoa undefined";
     44     var strDtata = "";
     45     if(typeof(data) !="string"){
     46         for(var i = 0 ; i < data.length;i++){
     47             strDtata +=String.fromCharCode(data[i]);
     48         }
     49     }else{
     50         strDtata = data;
     51     }
     52     return window.btoa(strDtata);
     53 };
     54 
     55 /**
     56  * 根据配置生成固定大小图片
     57  * @param width
     58  * @param height
     59  */
     60 Export2Image.prototype._scaleCanvas = function(width,height){
     61     var w = this.canvas.width;
     62     var h = this.canvas.height;
     63     width = width || w;
     64     height = height  || h;
     65 
     66     var newCanvas = document.createElement("canvas");
     67     newCanvas.width = width;
     68     newCanvas.height = height;
     69     var ctx = newCanvas.getContext("2d");
     70     ctx.drawImage(this.canvas,0,0,w,h,0,0,width,height);
     71     this.canvas = newCanvas;
     72 };
     73 
     74 /**
     75  * 获取canvas的Dataurl
     76  */
     77 Export2Image.prototype._getDataURL = function(){
     78     return this.canvas.toDataURL(this.type);
     79 };
     80 /**
     81  * 获取导出图片类型
     82  * @private
     83  */
     84 Export2Image.prototype._fixType = function(){
     85     var type = this.type.toLocaleLowerCase().replace(/jpg/i,"jpeg");
     86     var res = type.match(/png|jpeg|bmp|gif/)[0];
     87     this.type = "image/" + res;
     88 };
     89 
     90 /**
     91  * 获取数据
     92  */
     93 Export2Image.prototype.getData = function(){
     94     if(this.actualWidth && this.actualHeight){
     95         this._scaleCanvas(this.actualWidth,this.actualHeight);
     96     }
     97     var strData = "";
     98     if (/bmp/.test(this.type)) {
     99         var data = this._getImageData();
    100         strData = this._getBitmapImage(data);
    101     } else {
    102         strData = this._getDataURL();
    103     }
    104     return strData;
    105 }
    106 
    107 /**
    108  * 普通图片获取
    109  * @private
    110  */
    111 Export2Image.prototype._getImageData = function(){
    112     var w = this.canvas.width, h = this.canvas.height;
    113     return this.canvas.getContext('2d').getImageData(0, 0, w, h);
    114 };
    115 
    116 /**
    117  * 位图获取
    118  * @private
    119  */
    120 Export2Image.prototype._getBitmapImage = function(oData){
    121     var aHeader = [];
    122 
    123     var iWidth = oData.width;
    124     var iHeight = oData.height;
    125 
    126     aHeader.push(0x42); // magic 1
    127     aHeader.push(0x4D);
    128 
    129     var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes
    130     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
    131     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
    132     aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
    133     aHeader.push(iFileSize % 256);
    134 
    135     aHeader.push(0); // reserved
    136     aHeader.push(0);
    137     aHeader.push(0); // reserved
    138     aHeader.push(0);
    139 
    140     aHeader.push(54); // dataoffset
    141     aHeader.push(0);
    142     aHeader.push(0);
    143     aHeader.push(0);
    144 
    145     var aInfoHeader = [];
    146     aInfoHeader.push(40); // info header size
    147     aInfoHeader.push(0);
    148     aInfoHeader.push(0);
    149     aInfoHeader.push(0);
    150 
    151     var iImageWidth = iWidth;
    152     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
    153     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
    154     aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
    155     aInfoHeader.push(iImageWidth % 256);
    156 
    157     var iImageHeight = iHeight;
    158     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
    159     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
    160     aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
    161     aInfoHeader.push(iImageHeight % 256);
    162 
    163     aInfoHeader.push(1); // num of planes
    164     aInfoHeader.push(0);
    165 
    166     aInfoHeader.push(24); // num of bits per pixel
    167     aInfoHeader.push(0);
    168 
    169     aInfoHeader.push(0); // compression = none
    170     aInfoHeader.push(0);
    171     aInfoHeader.push(0);
    172     aInfoHeader.push(0);
    173 
    174     var iDataSize = iWidth*iHeight*3;
    175     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
    176     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
    177     aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
    178     aInfoHeader.push(iDataSize % 256);
    179 
    180     for (var i=0;i<16;i++) {
    181         aInfoHeader.push(0);    // these bytes not used
    182     }
    183 
    184     var iPadding = (4 - ((iWidth * 3) % 4)) % 4;
    185 
    186     var aImgData = oData.data;
    187 
    188     var strPixelData = "";
    189     var y = iHeight;
    190     do {
    191         var iOffsetY = iWidth*(y-1)*4;
    192         var strPixelRow = "";
    193         for (var x=0;x<iWidth;x++) {
    194             var iOffsetX = 4*x;
    195 
    196             strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+2]);
    197             strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+1]);
    198             strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX]);
    199         }
    200         for (var c=0;c<iPadding;c++) {
    201             strPixelRow += String.fromCharCode(0);
    202         }
    203         strPixelData += strPixelRow;
    204     } while (--y);
    205 
    206     var strEncoded = this._encodeData(aHeader.concat(aInfoHeader)) + this._encodeData(strPixelData);
    207 
    208     return  this._makeDataURI(strEncoded);
    209 };
    210 
    211 Export2Image.prototype._makeDataURI = function(strData){
    212     return "data:" + this.type + ";base64," + strData;
    213 }
    214 
    215 /**
    216  * 保存
    217  * @param data
    218  * @param fileName
    219  * @private
    220  */
    221 Export2Image.prototype._saveFile = function(data,fileName){
    222     try{
    223         //TODO:IE浏览器
    224          new ActiveXObject("Microsoft.XMLHTTP");
    225         var oImg = document.createElement("img");
    226         oImg.src = data;
    227         oImg.onload = function(){
    228             myWindow=window.open('','_blank','width=800,height=600');
    229             myWindow.document.write("<img src='"+data+"'>")
    230             myWindow.focus()
    231         }
    232     }catch(e){
    233          var saveLink = document.createElementNS("http://www.w3.org/1999/xhtml","a");
    234         saveLink.href = data;
    235         saveLink.download = fileName;
    236         var event = document.createEvent("MouseEvents");
    237         event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    238         saveLink.dispatchEvent(event);
    239     }
    240 
    241 };
    242 
    243 Export2Image.prototype.exportPic = function(){
    244     if(this.exportType == "html2Image"){
    245         if(typeof(html2canvas) !="function"){
    246             alert("需要引入html2canvas.js库文件");
    247             return;
    248         }
    249         var that = this;
    250         html2canvas(this.exportObj, {
    251             onrendered: function(canvas) {
    252                 that.canvas = canvas;
    253                 var data = that.getData();
    254                 var imgData = data.replace(that.type,'image/octet-stream');
    255                 that._saveFile(imgData,that.fileName);
    256             }
    257         });
    258     }else{
    259         var data = this.getData();
    260         var imgData = data.replace(this.type,'image/octet-stream');
    261         this._saveFile(imgData,this.fileName);
    262     }
    263 
    264 };
     1 <html>
     2 <meta http-equiv="X-UA-Compatible" content="chrome=1">
     3 <meta charset="utf-8">
     4 <head>
     5     <title>dom页面导出为图片</title>
     6     <style type="text/css">
     7         #wrap{
     8             width:400px;
     9             height:300px;
    10             line-height:300px;
    11             font-family: "Courier New", Courier, monospace;
    12             font-size: 18px;
    13             text-align: center;
    14             border:  1px solid #ccc;
    15             background-image: url("img/a.jpg");
    16             overflow: auto;
    17         }
    18 
    19     </style>
    20 </head>
    21 <body>
    22     <div id="wrap">这是DOM元素,相当于项目中的图形所在的div
    23     </div>
    24     <input type="button" value="html导出图片" onclick="htmlExportHandler();"/><br><hr/>
    25     <canvas id="myCanvas" width="600" height="400" style="background:yellowgreen"></canvas>
    26     <input type="button" value="canvas导出图片" onclick="canvasExportHandler();"/><br><hr/>
    27 
    28 </body>
    29 </html>
    30 <script type="text/javascript" src="js/html5.js"></script>
    31 <script type="text/javascript" src="js/html2canvas.js"></script>
    32 <script type="text/javascript" src="js/Export2Image.js"></script>
    33 <script>
    34 
    35 
    36     window.onload = function() {
    37         var canvas = document.getElementById("myCanvas");
    38         var ctx=canvas.getContext('2d');
    39         ctx.fillStyle='#FF0000';
    40         ctx.fillRect(10,10,200,100);
    41 
    42     };
    43 
    44     function htmlExportHandler(){
    45         var oContent = document.getElementById("wrap");
    46         new Export2Image(oContent,{type:"bmp",name:"html导出文件"}).export();
    47     }
    48 
    49     function canvasExportHandler(){
    50         new Export2Image("myCanvas").export();
    51     }
    52 
    53 </script>                                                                                                                          
  • 相关阅读:
    正则表达式(一个字符串翻转的例子)(http://www.cnblogs.com/hai98)
    电话号码正则表达式
    用哪种方法判断字符串为空更快速
    SQL内数据类型
    正则表达式基础(http://www.cnblogs.com/hai98)
    随机生成数
    C#源码 备份和恢复数据库
    ajax技术制作得在线歌词搜索功能
    ReadyGo新闻管理系统 1.5版 无任何使用限制
    最新完成的asp.net 2.0网站
  • 原文地址:https://www.cnblogs.com/tengri/p/5477741.html
Copyright © 2011-2022 走看看