微信H5保存分享图片

时间:2024-04-05 11:31:17

使用场景:

需实现一个微信分享的H5活动页,用户进行一个测试,提交答案后生成动态结果页,长按保存下载分享图片。

功能需求:

  • 图片内容动态生成
  • 图片带有用户头像及昵称
  • 显示图片与实际下载图片不一致,实际下载的图片附有分享二维码

实现思路:

  • 通过微信鉴权获取用户的头像和昵称
  • 根据用户提交的答案生成结果
  • 将实际需要转图片的dom节点通过设置层叠的方式使其不可见
  • 使用html2canvas将隐藏的dom节点转canvas,再将canvas转图片
  • 长按保存下载图片

具体实现:

第一步:微信鉴权获取用户的头像和昵称

通过微信鉴权获取用户头像和昵称,参见微信网络授权-获取用户信息

第二步:根据用户提交的答案生成结果

根据用户提交的答案生成结果,由于当前展示的页面和实际需要保存的图片不一致,所以需要通过设置position和z-index,将实际需要转为图片的dom节点“隐藏”于页面下。

第三步:html转图片

import html2canvas from 'html2canvas';

...

// html转图片
function convert2img() {
  let $share = document.querySelector('#share'); 
  html2canvas($share, {
    allowTaint: true,
    taintTest: false,
    scale: 2,
    width: $share.offsetWidth,
    height: $share.offsetHeight
  }).then(function (canvas) {
    // img为base64格式的图片
    let img = canvas.toDataURL('image/jpeg', 1.0);
    ...
  });
}

对于图片的优化处理可参见下方链接。

第四步:长按保存下载图片

微信自带长按保存图片的功能,所以需要实现的是,当用户长按“长按保存”时,如何让微信保存第三步中生成的分享图片。

实现关键:当用户长按不可见的图片,也能启用长按保存功能。
所以只需要将分享图片隐藏,并且设置它为最高层级即可。当用户长按保存时,实际长按的是被隐藏了的分享图片。

综合方案,实际的层叠关系如下:
微信H5保存分享图片

补充: 微信头像跨域问题

canvas对于图片资源具有同源限制,存在非同源图片时,后续采用的html2canvas方法会报错。当前的解决方案为服务端代理转发,node实现方式如下:

//app.js
var proxy = require('http-proxy-middleware');
...
var app = express();
...
var wx_options = {
    target: 'http://thirdwx.qlogo.cn', // 目标服务器
    changeOrigin: true, // 默认false,是否需要改变原始主机头为目标URL
    pathRewrite: {
        '^/wx_head/mmopen' : '/mmopen'     // 重写URL请求
    },
    onProxyReq: (proxyReq, req, res) => {
        proxyReq.setHeader('Referer', 'http://thirdwx.qlogo.cn')
    }
};
...
app.use('/wx_head', proxy(wx_options)); // 当请求到wx_head下时,转发请求
...
module.exports = app;

当页面调用图片时,更改微信头像前缀为:

// 原微信头像URL为"http://thirdwx.qlogo.cn/mmopen/..."
img.src = "http://www.xxx.com/wx_head/mmopen/..."

参考链接:

html2canvas官网
基于html2canvas实现网页保存为图片及图片清晰度优化