Skip to content

Instantly share code, notes, and snippets.

@ufologist
Created February 20, 2019 10:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ufologist/4ae1c9b03b7ea32d66d909e9c14e2d2b to your computer and use it in GitHub Desktop.
Save ufologist/4ae1c9b03b7ea32d66d909e9c14e2d2b to your computer and use it in GitHub Desktop.
生成带微信头像的图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>生成带微信头像的图片</title>
</head>
<body>
<div class="js-draw-content">
<h1>分享的海报形式图片</h1>
<p>包含微信用户的头像</p>
<div>
<!-- 为防止缓存非 CORS 请求的结果可以加上 crossorigin="anonymous" -->
<img class="js-img" src="http://thirdwx.qlogo.cn/mmopen/vi_32/Q3auHgzwzM6qNFBiaJGAseqIiboicfbZ9Cgf5tAOJwWfYmtqpM6f8YEtPXXriccoBVfnFE3kYMibBFFyWBALWKTRvsg/132">
</div>
</div>
<div>
<button class="js-base64-btn">获取图片的 base64 数据</button>
<br>
<button class="js-draw-btn">DOM元素生成图片</button>{ <label>useCORS: <input type="checkbox" checked class="js-usecors"></label>, <label>allowTaint: <input type="checkbox" class="js-allow-taint"></label> }<a href="//html2canvas.hertzen.com/configuration">?</a>
</div>
<hr>
<div class="js-result"></div>
<script src="//html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script>
(function() {
var resultEl = document.querySelector('.js-result');
var imgEl = document.querySelector('.js-img')
var originImgSrc = imgEl.src;
// 获取图片的 base64 数据
document.querySelector('.js-base64-btn').addEventListener('click', function() {
resultEl.innerHTML = '加载图片中...';
var nocacheParam = '_=' + Date.now();
var imgSrc = originImgSrc.indexOf('?') === -1 ? originImgSrc + '?' + nocacheParam : originImgSrc + '&' + nocacheParam;
var img = new Image();
img.onload = function() {
resultEl.innerHTML = '加载图片完成...';
// 将图片绘制到 canvas 上以获取到图片的数据
var canvas = document.createElement('canvas');
canvas.height = img.height;
canvas.width = img.width;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
resultEl.innerHTML = '正在获取图片的 base64 数据...';
try {
var dataUrl = canvas.toDataURL();
resultEl.innerHTML = '<h2>图片的 base64 数据(canvas.toDataURL):</h2>' + '<p style=" word-break:break-all">' + dataUrl + '</p>';
// 将图片的 src 替换成 base64 的图片数据, 避免使用 html2canvas 时再次遇到跨域的问题
imgEl.src = dataUrl;
} catch (error) {
resultEl.innerHTML = '<h2 style="color:red">获取图片的 base64 数据失败(canvas.toDataURL):</h2>' + error;
console.error(error);
}
};
// 当开启 crossOrigin 机制时, 服务器必须遵循 CORS 规范, 返回 Access-Control-Allow-Origin 头,
// 否则会被浏览器阻止(cancel)掉
// Access to Image at 'https://img.com/a' from origin 'http://domain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://domain.com' is therefore not allowed access.
img.onerror = function(event) {
resultEl.innerHTML = '<h2 style="color:red">加载图片失败(img onerror):</h2>' + JSON.stringify(event, null, 4);
console.error(event);
};
// 加载跨域的图片时必须让浏览器**执行跨域请求(CORS)**(开启 crossOrigin 机制),
// 否则将跨域的图片绘制到 canvas 上会导致 canvas 被污染,
// 执行 `canvas.toDataURL` 会因为安全风险而导致执行失败抛出异常
// Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
//
// A cross-origin request (i.e., with Origin: HTTP header) is performed.
// If the server does not give credentials to the origin site (by not setting the Access-Control-Allow-Origin HTTP header),
// the image will be tainted and its usage restricted.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
img.crossOrigin = 'anonymous';
img.src = imgSrc;
}, false);
// DOM元素生成图片
document.querySelector('.js-draw-btn').addEventListener('click', function() {
resultEl.innerHTML = '绘制到 canvas 上...';
html2canvas(document.querySelector('.js-draw-content'), {
// Whether to attempt to load images from a server using CORS
useCORS: document.querySelector('.js-usecors').checked,
// Whether to allow cross-origin images to taint the canvas
allowTaint: document.querySelector('.js-allow-taint').checked
}).then(function(canvas) {
resultEl.innerHTML = '正在生成图片...';
try {
var img = new Image();
img.style.width = canvas.style.width;
img.style.height = canvas.style.height;
img.src = canvas.toDataURL();
resultEl.innerHTML = '<h2>生成的图片:</h2>';
resultEl.appendChild(img);
} catch (error) {
resultEl.innerHTML = '<h2 style="color:red">生成图片失败:</h2>' + error + '<h2>Canvas:</h2>';
resultEl.appendChild(canvas);
console.error(error);
}
});
}, false);
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment