JavaScript基于用户照片姓名生成海报
前言
最近在为公司的一个比赛制作专题页,碰到一个使用参赛者上传的照片生成专属海报的需求,实现过程中用到了一些以前没用过的 api,也踩了一些坑,于是将其记录下来。
需求描述
- 用户点击按钮进行照片上传
- 照片上传完成后,将照片进行裁剪,并和海报背景、姓名等组合得到海报
- 将生成的海报上传
效果大概如下
海报背景
成品
实现过程
1、初始化 canvas
canvas#poster-canvas(width='960' height='1280') function initCanvas() { canvasCtx = document.getElementById("poster-canvas").getContext('2d'); }
2、绘制海报背景
海报背景为预先提供的一张照片,将其设置到一个隐藏的 img 标签里面,并且预留一个 canvas 元素用于绘制海报
img.poster-background(src='/assets/xxx/poster-background.jpeg')
页面加载完成后,将海报背景绘制到 canvas 内
$('img.poster-background').on('load', function () { var backgroundImg = $('img.poster-background')[0]; canvasCtx.drawImage(backgroundImg, 0, 0, 960, 1280); renderName(); });
海报背景绘制完成之后,需要将用户姓名绘制到特定位置。由于用户姓名长度不一,需要进行计算确定字体大小
function renderName() { var name = $('input[name="chName"]').val(); var fontSize; if (name.length < 3) { fontSize = 100; } else { fontSize = parseInt(320 / name.length); } canvasCtx.font = "bold " + fontSize + "px Courier New"; canvasCtx.fillStyle = "#de071b"; canvasCtx.fillText(name, 20, 1066); }
3、上传照片
使用 file 类型的 input 元素,因为页面上表现为点击按钮,使用经典的将 input 元素透明化并覆盖按钮的方法
a.upload-btn input#photo(type='file' name='photo' aept='image/jpeg, image/png') | 上传自己的照片生成专属海报 .upload-btn input { position: absolute; left: 0; : 0; opacity: 0; width: 100%; height: 68px; cursor: pointer; }
然后监听 input 元素的 change 事件,然后使用 FormData API 构造表单数据,使用 ajax 进行异步上传,照片上传完成之后。得到一个地址,将这个地址设置到页面上预留的一个 img 标签里面
$('#photo').on('change', function (e) { var file = e.target.files[0]; var type = file.type; if (type !== 'image/jpeg' && type !== 'image/png') { window.toastr.error('请上传 jpg 或 png 格式的图片'); } else { var formData = new FormData(); formData.append('avatar', file); $.ajax({ type: 'POST', url: '/upload_url', data: formData, contentType: false, processData: false, suess: function(result) { var avatarUrl = result.data.url; $('img.avatar').attr('src', avatarUrl); }, error: function(err) { } }); } });
4、绘制照片
海报中放置照片的区域为正方形,用户上传的照片却不一定,需要对照片进行裁剪,裁剪的原则为取照片中间部分。然后将裁剪参数传进 canvas 的 drawImage 方法,进行绘制
$('img.avatar').on('load', function () { var avatarImg = $('img.avatar')[0]; var originWidth = avatarImg.width; var originHeight = avatarImg.height; var newWidth, cutStartX, cutStartY; if (originWidth < originHeight) { newWidth = originWidth; cutStartX = 0; cutStartY = (originHeight - originWidth) / 2; } else if (originWidth > originHeight) { newWidth = originHeight; cutStartX = (originWidth - originHeight) / 2; cutStartY = 0; } else { newWidth = originWidth; cutStartX = 0; cutStartY = 0; } canvasCtx.drawImage(avatarImg, cutStartX, cutStartY, newWidth, newWidth, 0, 0, 960, 960); uploadPoster(); });
前面绘制海报背景和这里绘制照片,调用的是同一个方法,只不过后者多传进去了裁剪参数。需要注意的是,裁剪参数是在绘制位置之前传进去的,而不是简单的补在后面
canvasCtx.drawImage(backgroundImg, 0, 0, 960, 1280);
canvasCtx.drawImage(avatarImg, cutStartX, cutStartY, newWidth, newWidth, 0, 0, 960, 960);
5、上传海报
依然使用 FormData API,需要先用 canvas 构造一个 Blob 对象。新版本的 Chrome 和 Firefox 支持 canvas 的 toBlob 方法,可以直接使用
document.getElementById("poster-canvas").toBlob(function (blob) {});
其它浏览器里,可以先用 toDataURL方法得到 base64 格式的图片数据,再转为 Blob
var blob = dataURLtoBlob(document.getElementById("poster-canvas").toDataURL()); function dataURLtoBlob(dataurl) { if (dataurl.indexOf('base64') < 0) { dataurl = 'data:image/jpeg;base64,' + dataurl; } var arr = dataurl.split(','); var mime = arr[0].match(/:(.?);/)[1]; var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n); while (n --) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type: mime}); }
然后进行上传,步骤和前面上传照片一致
var formData = new FormData(); formData.append('poster', blob); $.ajax({ type: 'POST', url: '/upload_poster_url', data: formdata, contentType: false, processData: false, suess: function(result) { }, error: function(err) { } });
至此,整个流程完结。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
编程语言
- 宿迁百度关键词排名指南:实现精准营销的关键
- 四川SEO优化怎么做网络推广
- 立昂技术备案老域名收购:如何为您的业务赋能
- 安徽百度关键词seo贵不贵,一般需要多少钱
- 吉林百度快照排名怎么做电话营销
- 多伦新手做SEO怎么做
- 甘肃优化关键词排名推广怎么做论坛营销
- 沙雅SEO网站推广:提升您的在线可见性
- 四川SEO优化如何提升销售额和销售量
- 聂荣网站排名优化:提升网站可见性的全方位指
- 涞水SEO:提升地方企业在线可见性的策略
- 辽宁百度seo排名怎样做网站排名
- 临湘哪有关键词排名优化:提升网站可见度的关
- 黑龙江百度网站优化有没有优惠
- 凉城优化关键词排名推广:提升您的网络可见性
- 萝北整站优化:提升您网站流量和排名的全面指