将html页面生成图片,复制或保存该图片

2019-12-27  本文已影响0人  八重代
1、html页面生成图片

这一步比较简单,引入html2canvas.js即可

//这是一种写法,但是这种写法会导致浏览器窗口变小的时候截图不完整,具体原因我没找到,但是找到了另一种方法
html2canvas(document.getElementById("content"),{
    // windowWidth:710,
    windowHeight:$('#content').height(),
    // width:window.screen.availWidth,
    // height:window.screen.availHeight,
    width:430,//所得图片的width
    height:$('#content').height(),//所得图片的height
    x:0,//图片内容在图片上的位置,当有横向滚动条的时候一定要设置这一点
}).then(canvas => {
   var pageData = canvas.toDataURL('image/jpeg', 1.0);
    //隐藏任务信息div
   setTimeout(function () {
        $('#content').css('display','none');
   }, 50);            
});

//使用下面这种写法浏览器窗口缩小就不会造成截图不完整
//将要截图的区域,复制这个节点即可
var height = $('#content').height()
        //克隆节点,默认为false,不复制方法属性,为true是全部复制。
        var cloneDom = $('#content').clone(true);
        //设置克隆节点的css属性,因为之前的层级为0,我们只需要比被克隆的节点层级低即可。
        cloneDom.css({
            "background-color": "white",
            "position": "absolute",
            "top": "0px",
            "z-index": "-999",
            "height": height
        });
        //将克隆节点动态追加到body后面。
        $("body").append(cloneDom);
        html2canvas(cloneDom[0],{
            // windowWidth:710,
            windowHeight:$('#content').height(),
            // width:window.screen.availWidth,
            // height:window.screen.availHeight,
            taintTest: true, //检测每张图片都已经加载完成
            width:430,
            height:height,
            //x:0,
            //y:rect
        }).then(canvas => {
            //alert(242223235);
            var pageData = canvas.toDataURL('image/jpeg', 1.0);
            //隐藏任务信息div
            //$('#content').css('display','none');
            setTimeout(function () {
                $('#content').css('display','none');
                cloneDom.remove();
            }, 50);
            
            gettoken(pageData);
        });

基本简单的引用这样就可以实现,但是有一些注意的点
a、如果页面有竖直滚动条的时候,需要设置一下让滚动条滚动到顶部,$("body,html").scrollTop(0);
b、图片跨域问题,有两种方式,一种在引用的时候修改,即设置宽高的这个地方修改,另一种修改html2canvas.js,修改成allowTaint: true,useCORS: true
c、这里如果页面的内容里有https的网络图片好像不行,需要是http开头的,具体我不太记得了,当时我好像遇见了这个问题

2、简单实现图片下载

针对电脑端,这个的功能很简单,如果简单就是pc端,这个功能百度出来的代码很多都能实现

//这里传入的url即是上面的pageData = canvas.toDataURL('image/jpeg', 1.0);
//第一种方法
function saveimg(Url){
        var blob=new Blob([''], {type:'application/octet-stream'});
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = Url;
        a.download = Url.replace(/(.*\/)*([^.]+.*)/ig,"$2").split("?")[0];
        var e = document.createEvent('MouseEvents');
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);
        URL.revokeObjectURL(url);
    }
//第二种方法
//保存图片到本地
//调用的时候saveFile(pageData.replace("image/jpeg", "image/octet-stream"), new Date().getTime() + ".jpeg");
function saveFile(data, filename) {
        var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
        save_link.href = data;
        save_link.download = filename;

        var event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        save_link.dispatchEvent(event);
};
3、实现pc端复制生成的图片

这里生成的图片是base64格式的图片,复制针对浏览器好像不行,解决办法,将base64格式的图片上传到云端,上传成功后再根据返回的url实现复制
上传图片到七牛云

//上传base64的格式的图片到七牛云,注意URL的地址就好
//你的七牛云存储地址不同上传的地址也不同,这个具体看文档就好
function upimg(url){
   const uptoken = res.uptoken;  //上传验证信息,前端通过接口请求后端获得
   //console.log(uptoken);
   const pic = imgSource.replace('data:image/jpeg;base64,' ,'')       
   //base64后的字符串
   var key = btoa(username+new Date().getTime()+parseInt(Math.random()*10)+".jpg"); // 文件名
   const url = "http://upload-z2.qiniup.com/putb64/-1/key/"+key;
   var xhr = new XMLHttpRequest();; //非华东空间需要根据注意事项
   //const xhr = new XMLHttpRequest();
   xhr.onreadystatechange=()=>{
       if (xhr.readyState==4){
           const dataInfo = JSON.parse(xhr.response) //将返回的字符串转化为JSON对象
            //console.log(dataInfo)
            var imgurl = '七牛云配置的域名'+dataInfo.key;
                        //copyToClip(imgurl);
       }
    }

    xhr.open("POST", url, true);
    xhr.setRequestHeader("Content-Type", "application/octet-stream");
    xhr.setRequestHeader("Authorization", `UpToken ${uptoken}`);
    xhr.send(pic);
}
//获取上传七牛云的token,这个需要调用后台的接口获取
function gettoken(){
    var ajax = new XMLHttpRequest();
    ajax.open('GET', '/outsource/index/gettoken2', false);
    ajax.setRequestHeader("If-Modified-Since", "0");
    ajax.send();
     if (ajax.status === 200) {
          //JSON.parse(ajax.responseText);
         var res = ajax.responseText;
         //console.log('custom uptoken_func:' + res.uptoken);
         return res.uptoken;
      } else {
          return '';
       }
}
//我这边后台用的php,将后台的代码贴上,引用这个之前先要引入七牛云的sdk
public function gettoken2()
    {
        vendor('Qiniu.autoload');
        // 需要填写你的 Access Key 和 Secret Key
        $ak = '你的ak';
        $sk = '你的sk';
        // 构建鉴权对象
        // 要上传的空间
        $bucket = '你的空间名';
        $auth = new Auth($ak, $sk);

        $key = '上传7牛时,文件的名字';

        $token = $auth->uploadToken($bucket);
        $data['uptoken'] = $token;
        /*dump(json($data));die;*/
        return json($data);
    }
//实现复制图片
//这里的content就是上传图片到七牛云的返回的地址
function copyToClip(content, message) {
        //document.getElementById('img').setAttribute('src', content);
        var aux = document.createElement("div");
        var img1 = document.createElement("img");
        $(aux).html(img1);
        img1.setAttribute("src", content);
        document.body.appendChild(aux);
        //Make the container Div contenteditable
        $(aux).attr("contenteditable", true);
        //Select the image
        SelectText($(aux).get(0));
        //Execute copy Command
        //Note: This will ONLY work directly inside a click listenner
        document.execCommand('copy');
        //Unselect the content
        window.getSelection().removeAllRanges();
        //Make the container Div uneditable again
        $(aux).removeAttr("contenteditable");
        //aux.remove();
        setTimeout(function () {
            aux.remove();
        }, 50);
        //Success!!
        $("body").removeClass("notclick");
        layer.closeAll("loading");
        layer.alert('复制图片成功');
    }

    //选择区域
    function SelectText(element) {
        var doc = document;
        if(doc.body.createTextRange) {
            var range = document.body.createTextRange();
            range.moveToElementText(element);
            range.select();
        } else if(window.getSelection) {
            var selection = window.getSelection();
            var range = document.createRange();
            range.selectNodeContents(element);
            selection.removeAllRanges();
            selection.addRange(range);
        }
    }

注:其实这里使用clipboard.js也可以实现复制图片,但是这个图片要在页面上显示才可以,并且图片的地址不可以是https开头,下面将使用这个js的方法贴上

//html部分
<!-- 生成图片的div -->
    <div hidden id="div1">
        <div id="copyimgdiv">
            <img id="copyimg"/>
        </div>
        <button id="copyimgbtn"></button>
    </div>
js部分
   $('#div1').show();
   $('#copyimg').attr('src',imgurl);
   $('#copyimgbtn').click();
   $('#copyimgbtn').click(function(){
        var a = document.getElementById("copyimgdiv");
        //console.log(a);
        copyFunction(a, "#copyimgbtn", "复制成功");
    })

    var copyFunction = function (t, a, i) {
        var e = new ClipboardJS(a, {
            target: function () {
                return console.log(t, a),t
            }
            });
            e.on("success", function (t) {
                $('#div1').hide();
                $("body").removeClass("notclick");
                layer.closeAll("loading");
                layer.alert('复制成功');
                t.clearSelection()
            }),
            e.on("error", function (t) {
                $('#div1').hide();
                $("body").removeClass("notclick");
                layer.closeAll("loading");
                console.log('复制失败');
                t.clearSelection()
            })
    };
4、ipad下载图片

ipad下载图片,下载下来的是一个文件,粘贴到微信,有的版本太低的不会直接显示这张图片,所以就换了一个思路,浏览器自带的功能有长按图片会弹出选项框,点击保存图片就可以保存图片到相册
实现就是在页面隐藏一个div,将这个div覆盖整个屏幕,把img放在这个div里即可,我这边还是将图片上传到七牛云之后然后显示在页面上

//css部分
.taskimg{
        display: none;
        z-index: 999;
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
 }
 .taskimg div{
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        
        background:rgba(0, 0, 0, 0.2);
        display: flex;
        justify-content: center;
        align-items: center;
 }
 .taskimg div img{
        width: 400px;
        height: auto;
 }
//html部分
<div class="taskimg">
     <div>
          <img id="taskimg"/>
      </div>
</div>
//js部分
//这里的imgurl就是上传图片到七牛云返回的地址
$('.taskimg').css('display','block');
$("body").removeClass("notclick");
$('#taskimg').attr('src',imgurl);
5、手机端下载图片到手机相册

这里困扰了我很久,我一开始都是想着使用js实现,但是其实用后台来实现更简单,但是ios的自带的浏览器不行,我自己本地的手机是qq浏览器没问题,像我这种写法,ipad的uc浏览器也能将图片下载到本地,但不会出现在相册里

//js部分
//imgurl为上传图片到七牛云的返回地址
function baocunimg(imgurl){
     var a = document.createElement('a')
     a.href = '/outsource/highprice/download?img='+imgurl;
     //a.download = ''
     // 触发a链接点击事件,浏览器开始下载文件
     a.click()
}
//php后台部分
 function download($path = 'images/')
    {
        $file = input('get.img');;
        ob_start();
        ob_clean();
        header('Content-Type: application/octet-stream');
        header('Content-Transfer-Encoding: binary');
        header("Accept-Ranges:  bytes ");
        header('Content-Disposition: attachment;filename=' . basename($file));
        readfile($file);
        $img = ob_get_contents();
        ob_end_clean();
        echo $img;
        exit();
    }
最后附上判断到底是手机端、ipad、pc端访问
可以参考这个网址https://github.com/matthewhudson/current-device
下面是我这个项目的使用方法
 a、将下面的代码复制到一个空白的js文件
/*!
 * current-device v0.9.1 - https://github.com/matthewhudson/current-device
 * MIT Licensed
 */
!function(n,o){"object"==typeof exports&&"object"==typeof module?module.exports=o():"function"==typeof define&&define.amd?define([],o):"object"==typeof exports?exports.device=o():n.device=o()}(window,function(){return function(n){var o={};function e(t){if(o[t])return o[t].exports;var r=o[t]={i:t,l:!1,exports:{}};return n[t].call(r.exports,r,r.exports,e),r.l=!0,r.exports}return e.m=n,e.c=o,e.d=function(n,o,t){e.o(n,o)||Object.defineProperty(n,o,{enumerable:!0,get:t})},e.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},e.t=function(n,o){if(1&o&&(n=e(n)),8&o)return n;if(4&o&&"object"==typeof n&&n&&n.__esModule)return n;var t=Object.create(null);if(e.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:n}),2&o&&"string"!=typeof n)for(var r in n)e.d(t,r,function(o){return n[o]}.bind(null,r));return t},e.n=function(n){var o=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(o,"a",o),o},e.o=function(n,o){return Object.prototype.hasOwnProperty.call(n,o)},e.p="",e(e.s=0)}([function(n,o,e){n.exports=e(1)},function(n,o,e){"use strict";e.r(o);var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},r=window.device,i={},a=[];window.device=i;var c=window.document.documentElement,d=window.navigator.userAgent.toLowerCase(),u=["googletv","viera","smarttv","internet.tv","netcast","nettv","appletv","boxee","kylo","roku","dlnadoc","pov_tv","hbbtv","ce-html"];function l(n,o){return-1!==n.indexOf(o)}function s(n){return l(d,n)}function f(n){return c.className.match(new RegExp(n,"i"))}function b(n){var o=null;f(n)||(o=c.className.replace(/^\s+|\s+$/g,""),c.className=o+" "+n)}function p(n){f(n)&&(c.className=c.className.replace(" "+n,""))}function w(){i.landscape()?(p("portrait"),b("landscape"),y("landscape")):(p("landscape"),b("portrait"),y("portrait")),v()}function y(n){for(var o in a)a[o](n)}i.macos=function(){return s("mac")},i.ios=function(){return i.iphone()||i.ipod()||i.ipad()},i.iphone=function(){return!i.windows()&&s("iphone")},i.ipod=function(){return s("ipod")},i.ipad=function(){var n="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1;return s("ipad")||n},i.android=function(){return!i.windows()&&s("android")},i.androidPhone=function(){return i.android()&&s("mobile")},i.androidTablet=function(){return i.android()&&!s("mobile")},i.blackberry=function(){return s("blackberry")||s("bb10")||s("rim")},i.blackberryPhone=function(){return i.blackberry()&&!s("tablet")},i.blackberryTablet=function(){return i.blackberry()&&s("tablet")},i.windows=function(){return s("windows")},i.windowsPhone=function(){return i.windows()&&s("phone")},i.windowsTablet=function(){return i.windows()&&s("touch")&&!i.windowsPhone()},i.fxos=function(){return(s("(mobile")||s("(tablet"))&&s(" rv:")},i.fxosPhone=function(){return i.fxos()&&s("mobile")},i.fxosTablet=function(){return i.fxos()&&s("tablet")},i.meego=function(){return s("meego")},i.cordova=function(){return window.cordova&&"file:"===location.protocol},i.nodeWebkit=function(){return"object"===t(window.process)},i.mobile=function(){return i.androidPhone()||i.iphone()||i.ipod()||i.windowsPhone()||i.blackberryPhone()||i.fxosPhone()||i.meego()},i.tablet=function(){return i.ipad()||i.androidTablet()||i.blackberryTablet()||i.windowsTablet()||i.fxosTablet()},i.desktop=function(){return!i.tablet()&&!i.mobile()},i.television=function(){for(var n=0;n<u.length;){if(s(u[n]))return!0;n++}return!1},i.portrait=function(){return screen.orientation&&Object.prototype.hasOwnProperty.call(window,"onorientationchange")?l(screen.orientation.type,"portrait"):i.ios()&&Object.prototype.hasOwnProperty.call(window,"orientation")?90!==Math.abs(window.orientation):window.innerHeight/window.innerWidth>1},i.landscape=function(){return screen.orientation&&Object.prototype.hasOwnProperty.call(window,"onorientationchange")?l(screen.orientation.type,"landscape"):i.ios()&&Object.prototype.hasOwnProperty.call(window,"orientation")?90===Math.abs(window.orientation):window.innerHeight/window.innerWidth<1},i.noConflict=function(){return window.device=r,this},i.ios()?i.ipad()?b("ios ipad tablet"):i.iphone()?b("ios iphone mobile"):i.ipod()&&b("ios ipod mobile"):i.macos()?b("macos desktop"):i.android()?i.androidTablet()?b("android tablet"):b("android mobile"):i.blackberry()?i.blackberryTablet()?b("blackberry tablet"):b("blackberry mobile"):i.windows()?i.windowsTablet()?b("windows tablet"):i.windowsPhone()?b("windows mobile"):b("windows desktop"):i.fxos()?i.fxosTablet()?b("fxos tablet"):b("fxos mobile"):i.meego()?b("meego mobile"):i.nodeWebkit()?b("node-webkit"):i.television()?b("television"):i.desktop()&&b("desktop"),i.cordova()&&b("cordova"),i.onChangeOrientation=function(n){"function"==typeof n&&a.push(n)};var m="resize";function h(n){for(var o=0;o<n.length;o++)if(i[n[o]]())return n[o];return"unknown"}function v(){i.orientation=h(["portrait","landscape"])}Object.prototype.hasOwnProperty.call(window,"onorientationchange")&&(m="orientationchange"),window.addEventListener?window.addEventListener(m,w,!1):window.attachEvent?window.attachEvent(m,w):window[m]=w,w(),i.type=h(["mobile","tablet","desktop"]),i.os=h(["ios","iphone","ipad","ipod","android","blackberry","macos","windows","fxos","meego","television"]),v(),o.default=i}]).default});
//# sourceMappingURL=current-device.min.js.map

b、在页面上引入创建这个js文件
然后直接使用就可以了
device.mobile(),这个是手机
device.tablet(),这个是平板
device.desktop(),这个是电脑

最后附上实现pc端浏览器复制文字
function copytext(obj){
        var text=$(obj).parent().data('id');
        var oInput = document.createElement('input');
        oInput.value = text;
        document.body.appendChild(oInput);
        oInput.select(); // 选择对象
        document.execCommand("Copy"); // 执行浏览器复制命令
        oInput.className = 'oInput';
        oInput.style.display='none';
        layer.alert('复制成功');

}
上一篇下一篇

猜你喜欢

热点阅读