用html2canvas快速生成海报分享图片,画布和图片互转,要看到最后啊,优化的在后面!!!

上次分享的通过php方式生成的海报图片总有写字是模糊的,多次调试没有解决问题,后来干脆想办法在前端页面直接搞,请教了前端的大佬后分享了一个

很不错的js脚本,可以快速实现html转换成canvas画布,然后自行通过其他逻辑下载截图即可。


效果图:

分享图片 (2).png



html2canvas.js引入到项目进行操作即可,可以对指定的元素进行“截图”模式。


特别注意:图片千万不要用background方式设置,否则会模糊,之前用span的background设置图片,发现很模糊,经过查阅资料发现用img标签替代就行了,这样才很清晰。


案例代码(自己非专业前端,不喜勿喷,基于weui排版写的页面):

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>海报分享</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/weui/css/weui.css">
    <link rel="stylesheet" href="/static/weui/css/weuix.css">



    <style>
        .info-text{
            width: 70%;
            float: left;
        }
        .info-img{
            width: 30%;
            float: right;
            line-height: 100%;
        }
        .info-img img{
            max-height: 100%;
            max-width: 100%;

        }
        .info-img .qrcode{
            width: 100%;
        }
        #content{
            margin:0 auto;
            max-width: 650px;
        }
        .tip{
            font-size: 18px;
            text-align: center;
            padding: 10px;
            font-weight: bold;
        }
    </style>
</head>

<body ontouchstart>

<div>

    <div id="content">
        <ul>
            <li style="width: 100%">
                <img src="/upload/test/share/1.jpg"  style="max-width: 100%;"/>
            </li>
            <li style="width: 100%;background: white;overflow: hidden;padding: 10px">
                <div>
                    <b style="overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;">正宗初生蛋小个头40枚10枚散养农村散养初生鸡蛋现捡新鲜鸡蛋批发</b> <br>
                    ¥ <b style="color: red">27.9</b>
                    <div style="color: grey;font-size: 14px">识别右侧的二维码进入了解详情</div>
                </div>
                <div>
                    <img src="/upload/test/share/qc.png" alt="">
                </div>
                <div style="clear: both"></div>

            </li>
            <li>
                <img src="/upload/test/share/1.jpg" style="max-width:100%"/>
            </li>

            <li>
                <img src="/upload/test/share/6.jpg" style="max-width:100%"/>
            </li>
            <li>
                 <img src="/upload/test/share/2.jpg" style="max-width:100%"/>
            </li>
            <li>
                <img src="/upload/test/share/3.jpg" style="max-width:100%"/>
            </li>
            <li>
                 <img src="/upload/test/share/4.jpg" style="max-width:100%"/>
            </li>
            <li>
                 <img src="/upload/test/share/5.jpg" style="max-width:100%"/>
            </li>
        </ul>
    </div>
    <div></div>
    <div>
        <p class="f-red tip">请长按图片保存到本地并分享</p>
    </div>

</div>
<br>
<br>
<script src="/static/weui/js/zepto.min.js"></script>
<script src="/static/weui/js/zepto.weui.js"></script>
<script type="text/javascript" src="/static/js/html2canvas.min.js"></script>
<script type="text/javascript">
    //用JavaScript将画布保持成图片格式
    function convertCanvasToImage(canvas) {
        var image = new Image();
        image.src = canvas.toDataURL("image/png");
        return image;
    }
    $.showLoading();
    var c = document.getElementById("content")
    var options = {
        dpi: 300,
        scale: 2, // 添加的scale 参数
       // width:500,

        useCORS: true // 【重要】开启跨域配置
    };

    html2canvas(c,options).then(function(canvas) {
        //$(".res").html(canvas)
        $(c).html("<img src='"+canvas.toDataURL('image/png')+"' style='max-width: 100%'/>")
        /*var a = document.createElement('a')
        //a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
       // a.download = '分享图片' // 设定下载名称
        //a.className='weui-btn weui-btn-area weui-btn_primary'
       // a.innerHTML='保存海报'
        $(".btn").html(a)*/
    });
    $.hideLoading();

</script>
</body>
</html>


html2canvas的参数 http://html2canvas.hertzen.com/configuration:


微信截图_20210717132837.png


微信截图_20210717133001.png




调整js代码,设置scale比例,并自动下载为png:

var c = document.getElementById("content")
var options = {
    scale:1.3,//按比例缩放
    dip:2000,//没有发现有用
}
html2canvas(c,options).then(function(canvas) {
    $(c).html(canvas)

    var a = document.createElement('a')
    a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
    a.download = '分享图片' // 设定下载名称
    a.click() // 点击触发下载

});




另外,分享两个画布和图片互转的函数(或许有用哦):

//用JavaScript将画布保持成图片格式
function convertCanvasToImage(canvas) {
    var image = new Image();
    image.src = canvas.toDataURL("image/png");
    return image;
}

//使用JavaScript将图片拷贝进画布
function convertImageToCanvas(image) {
    var canvas = document.createElement("canvas");
    canvas.width = image.width;
    canvas.height = image.height;
    canvas.getContext("2d").drawImage(image, 0, 0);

    return canvas;
}


遇到的坑和解决方案


问题1:图片跨域问题,比如拉取第三方平台的图片无法加载

解决:搭建本地图片资源转发服务,这里我用timthumb.php做,可以看这篇文章 如何在PHP中动态调整图像大小?今天分享这个小小的timthumb.php满足你的需求


问题2:图片截图显示不完整问题,滚动到下面开始截图时顶部空白

解决:页面加载完成后开始截图设置回到最顶部:document.body.scrollTop = document.documentElement.scrollTop = 0;


问题3:在移动端无法显示图片的问题,导致小图都不显示

解决:还是跨域问题,移动端和web端不一样,给图片添加匿名跨域属性:crossorigin="anonymous" 并设置useCORS: true // 【重要】开启跨域配置(不需要设置allowTaint: true,//允许跨域图片),然后就解决了。


问题4:进入页面直接生成的方式还是没有完整截图,经常只有部分

解决:进入页面后等页面加载完成设置一个延迟渲染,比如1秒:

 setTimeout(function (){
            start();
        },1000)


问题5:图片过大也会导致生成画布不完整

解决:还是通过图片代理,重新设置图片的大小


优化后完整版

<!doctype html>
<html lang="zh">
<head>
    <meta charset="utf-8">
    <title>海报分享</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/weui/css/weui.css">
    <link rel="stylesheet" href="/static/weui/css/weuix.css">



    <style>
        .info-text {
            width: 70%;
            float: left;
        }

        .info-img {
            width: 30%;
            float: right;
            line-height: 100%;
        }

        .info-img img {
            max-height: 100%;
            max-width: 100%;
        }

        .info-img .qrcode {
            width: 100%;
        }

        #content {
            margin: 0 auto;
            max-width: 800px;
            /*border: 2px chartreuse dashed;*/
        }

        .tip {
            font-size: 18px;
            text-align: center;
            padding: 10px;
            font-weight: bold;
        }

        img.s-img {
            height: 121px;
        }

        .weui-panel {
            background-color: #FFFFFF;
            margin-top: 10px;
            position: unset;
            overflow: hidden;
            /* bottom: 0; */
            text-align: center;
        }
    </style>
</head>

<body ontouchstart>

<div class="page-bd-15">

    <div class="weui-feeds" id="content">
        <ul>
            <li style="width: 100%;text-align: center">
                <img src="https://source.alipay168.cn/wxauth.alipay168.cn/mstore/1f0e3dad99908345f7439f8ffabdffc4.png?v=1584009797" style="max-width:100%" />
            </li>
            <li style="width: 100%;background: white;overflow: hidden;padding: 10px;max-width: 100%">
                <div class="info-text">
                    <b style="overflow: hidden;text-overflow: ellipsis; display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;">爆款格蒙网红7天迷你口红套装多色一盒持久不脱色国货彩妆</b> <br>
                    ¥ <b style="color: red">28.99</b>
                    <div style="color: grey;font-size: 14px">识别右侧的二维码进入了解详情</div>
                </div>
                <div class="info-img">
                    <img class="qrcode" src="http://wei.test.top/upload/mstore/poster/qrcode/19_1f0e3dad99908345f7439f8ffabdffc4.png" alt="">
                </div>
                <div style="clear: both"></div>

            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009531198704.jpg&w=121&q=100" style="max-width:100%"/>
            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532970739.jpg&w=121&q=100" style="max-width:100%"/>
            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532388616.jpg&w=121&q=100" style="max-width:100%"/>
            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532120428.jpg&w=121&q=100" style="max-width:100%"/>
            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009533453186.jpg&w=121&q=100" style="max-width:100%"/>
            </li>
            <li style="text-align: center">
                <img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009533432512.jpg&w=121&q=100" style="max-width:100%"/>
            </li>



        </ul>
    </div>
    <div class="res"></div>
    <div class="weui-panel" >
        <p class="f-red tip">请长按图片保存到本地并分享</p>
    </div>

</div>
<br>
<br>
<script src="/static/weui/js/zepto.min.js"></script>
<script src="/static/weui/js/zepto.weui.js"></script>
<script type="text/javascript" src="/static/js/html2canvas.min.js"></script>
<script type="text/javascript">

    function start(){
        //先跳到最顶端(如果有操作按钮在底部的特别重要)
        document.body.scrollTop = document.documentElement.scrollTop = 0;
        var c = document.getElementById("content")
        var options = {
            dpi: 300,
            scale: 2, // 添加的scale 参数
            //width:500,
            //height:1000,
            async:true,//是否异步
            onclone:function(){
                $.showLoading('海报生成中...');
            },
            proxy:null,//Url到 代理 ,用于加载跨源图像。如果留空,则不会加载跨原始图像。
            imageTimeout:10000,//加载图像的超时(以毫秒为单位,设置 0 为禁用超时
            // allowTaint: true,//允许跨域图片
            taintTest: false,//是否在渲染前测试图片
            useCORS: true // 【重要】开启跨域配置
        };
        html2canvas(c,options).then(function(canvas) {
            $.hideLoading();
            $(c).html("<img src='"+canvas.toDataURL('image/png')+"' style='max-width: 100%'/>");

            /*var a = document.createElement('a')
            a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
            a.download = '分享图片' // 设定下载名称
            a.className='weui-btn weui-btn-area weui-btn_primary'
            a.innerHTML='保存海报'
            $(".btn").html(a)*/
        });


    }

    //用JavaScript将画布保持成图片格式
    function convertCanvasToImage(canvas) {
        var image = new Image();
        image.src = canvas.toDataURL("image/png");
        return image;
    }
    $(function (){
        setTimeout(function (){
            start();
        },1000)
    })

</script>
</body>
</html>


效果:

下载.png

评论/留言