需要将一个背景图+动态获取的文字+微信头像拼接成一张图片,用户可长按保存最终图片,难免就是要将html转换成图片。

最初想要自己用canvas画,但是略麻烦,后来发现了html2canvas这个插件,先将html转成canvas,再生成图片。

使用起来也很简单:

setTimeout(function () {

html2canvas($('#img_html')[0]).then(function (canvas) {

var img = new Image()

img.src = canvas.toDataURL('image/jpeg')

img.style.cssText += 'position:absolute;width:100%;left:0;top:0;'

$('#result').append(img)

})

}, 1000)

但是踩坑不少,罗列如下:

因为html是动态生成的,所以最好加上setTimeout延时转换成canvas,不然可能html的dom元素还没加载完。

canvas.toDataURl()该方法是将canvas转成图片,如果html中有跨域请求的图片资源,那么canvas就会报错不支持跨域。所以只好将微信头像先上传到服务器的文件系统,请求图片时,带上允许跨域的响应头:Access-Control-Allow-Origin: *

要转换成图片的 html,其css样式要有几点注意:

亲测不能使用rem为单位定义文字大小、元素宽高等,不然无法显示该元素

不能添加background,假如设置背景颜色为红色或者一张背景图,莫名其妙会多出一个元素,如下所示:

e2a8a511c315

原始html

e2a8a511c315

生成的图片

4.canvas.toDataURl()生成的图片是base64的格式data:image/jpeg;base64,/9j/4AAQ...,可以直接作为img标签的src。

但是由于是小程序内嵌H5,且图片资源过大,在某些机型(常见Ios)的微信小程序里面会限流。当生成图片,准备渲染的时候,微信要么会直接白屏,要么就是会弹框提醒:该小程序继续运行会影响微信的使用,强制退出该小程序。

解决方法

function dataURLtoBlob (data_url) {

let arr = data_url.split(',')

let mime = arr[0].match(/:(.*?);/)[1]

let bstr = atob(arr[1])

let n = bstr.length

let u8arr = new Uint8Array(n)

let blob = false

while (n--) {

u8arr[n] = bstr.charCodeAt(n)

}

try {

blob = new Blob([u8arr], { type: mime })

} catch (e) {}

return blob

}

如上所示,可将base64转成二进制流,资源会减小1到1.5倍。

不过在某些安卓国产机型上,不支持长按保存该二进制流图片,所以可以设置仅Ios上转换为二进制图片。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐