小程序生成海报,在小程序端是很容易实现,不过最近遇到一个需要在后台实现海报生成的需求,就研究了一下html2canvas生成海报的方法
需求
在后台商品列表,点击推广,生成包含商品图片和小程序码的推广海报,商品图片存放在阿里云oss,存在跨域问题
实现
<-- 小程序码在服务端通过小程序sdk获取后保存在服务端 -->
<div id="poster">
<div class="goods_pic">
<img src="https://dev.oss-cn-hangzhou.aliyuncs.com/test.png">
</div>
<div id="mini_qrcode">
<img src="https://abc.com/mini.png">
</div>
</div>
<div class="save_btn" @click="savecanvas">
保存图片
</div>
// 创建并生成海报
function savecanvas() {
var shareContent = $('#poster')[0]; // dom对象
var width = shareContent.offsetWidth; //获取dom 宽度
var height = shareContent.offsetHeight; //获取dom 高度
var canvas = document.createElement("canvas");
var scale = 1; //定义任意放大倍数 支持小数
canvas.width = width * scale; //定义canvas 宽度 * 缩放
canvas.height = height * scale; //定义canvas高度 *缩放
canvas.style.width = width * scale + 'px';
canvas.style.height = height * scale + 'px';
canvas.getContext("2d").scale(scale, scale); //获取context,设置scale
var opts = {
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
logging: true, //日志开关,便于查看html2canvas的内部执行流程
width: width, //dom 原始宽度
height: height,
useCORS: true // 【重要】开启跨域配置
};
html2canvas(shareContent, opts).then(canvas => {
var imgUri = canvas.toDataURL("image/png")
let aLink = document.createElement("a");
aLink.style.display = "none";
aLink.href = imgUri;
aLink.download = "海报图片.png";
// 触发点击-然后移除
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
});
};
跨域问题
虽然开启了 html2canvas 的跨域配置 useCORS,但是生成的海报商品图片位置为空,所以考虑替换方案,直接在服务端获取图片的base64内容展示在前端
// 使用curl 下载图片
function curlFileGetContent($url, $path) {
$handler = curl_init();
$fp = fopen($path, 'wb');
curl_setopt($handler, CURLOPT_URL, $url);
curl_setopt($handler, CURLOPT_FILE, $fp);
curl_setopt($handler, CURLOPT_HEADER, 0);
curl_setopt($handler, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($handler, CURLOPT_TIMEOUT, 60);
curl_exec($handler);
curl_close($handler);
fclose($fp);
return $path;
}
// 将图片转为base64
function base64EncodeImage($image_file) {
$image_info = getimagesize($image_file);
$image_data = fread(fopen($image_file, 'r'), filesize($image_file));
$base64_image = 'data:' . $image_info['mime'] . ';base64,' . chunk_split(base64_encode($image_data));
return $base64_image;
}
以上,解决了html2canvas跨域图片不显示的问题
其他方案
后端支持:阿里云 header头中设置 Access-Control-Allow-Origin: *