整体方案
- 获取gif图对每一帧图片和延迟
- 通过canvas来对每一帧图片进行绘制
- 把绘制后的图片结合每帧延迟重新生成gif
第一步:获取gif图的每一帧
我们可以通过libgif(github.com/buzzfeed/li…) 这个库来实现这个功能。
例子:
<img src="./example1_preview.gif" rel:animated_src="./example1.gif"
width="360" height="360" rel:auto_play="1" rel:rubbable="1" />
<script type="text/javascript">
?('img').each(function (img_tag) {
if (/.*\.gif/.test(img_tag.src)) {
var rub = new SuperGif({ gif: img_tag } );
rub.load(function(){
console.log('oh hey, now the gif is loaded');
for (var i = 1; i <= rub.get_length(); i++) {
// 遍历gif实例的每一帧
rub.move_to(i);
var canvas = rub.get_canvas();
}
});
}
});
</script>
第二步:使用canvas重新绘制,添加文字
canvas添加文字例子:
var canvas = document.createElement('canvas');
var context = canvas.getContext("2d");
context.font = '28px bold 黑体';
context.fillStyle = 'red';
context.textAlign = 'center';
context.fillText('添加文字'+ i, 80, 50);
第三步 重新绘制gif
可以使用gif.js这个库(github.com/jnordberg/g…)
例子:
var gif = new GIF({
workers: 2,
quality: 10
});
// add an image element
gif.addFrame(imageElement);
// or a canvas element
gif.addFrame(canvasElement, {delay: 200});
// or copy the pixels from a canvas context
gif.addFrame(ctx, {copy: true});
gif.on('finished', function(blob) {
window.open(URL.createObjectURL(blob));
});
gif.render();
整体例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>gif add text</title>
</head>
<script src="gif.js"></script>
<script src="libgif.js"></script>
<body>
</body>
<script>
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.addEventListener('change', function (e) {
console.time('gifaddtext');
preLoadGif(input.files[0]);
});
document.body.appendChild(input);
preLoadGif= function (gifSource) {
var gifImg = document.createElement('img');
var reader = new FileReader();
reader.readAsDataURL(gifSource);
reader.onloadend = function (e) {
var objUrl = e.target.result;
// gif库需要img标签配置下面两个属性
var img = new Image();
img.src = objUrl;
img.onload = function () {
var width = this.width;
var height = this.height;
// 新建gif实例
var rub = new SuperGif({ gif: gifImg } );
var gif = new GIF({
workers: 10, // 启用worker数。
quality: 100, // 图像质量
width: width,
height: height,
workerScript:'./gif.worker.js'
});
rub.load(function () {
for (var i = 1; i <= rub.get_length(); i++) {
// 遍历gif实例的每一帧
rub.move_to(i);
var canvas = rub.get_canvas();
// 通过源码可以看到lib gif 是可以获取到每一帧的延迟的,为了方便,修改了源码481行,在每一帧都返回图片的数据
var delay = canvas.frames[i - 1].delay;
var canvas2 = document.createElement('canvas');
canvas2.width = width;
canvas2.height = height;
var context = canvas2.getContext("2d");
context.drawImage(canvas, 0, 0, canvas2.width, canvas2.height);
context.font = '28px bold 黑体';
context.fillStyle = 'red';
context.textAlign = 'center';
context.fillText('添加文字'+ i, 80, 50);
gif.addFrame(context, {copy: true, delay: delay * 10});
}
gif.on('finished', function(blob) {
console.timeEnd('gifaddtext');
alert('生成成功!');
window.open(URL.createObjectURL(blob));
});
gif.render();
});
}
gifImg.setAttribute('rel:animated_src', objUrl)
gifImg.setAttribute('rel:auto_play', '0')
gifImg.style.display = 'none';
document.body.appendChild(gifImg);
}
}
</script>
</html>