之前做了一个h5项目,核心功能是上传图片,进行裁剪后与其他页面部分合成到一个图片作为海报进行保存。实际做出来的功能如下所示,这里我是用pc浏览器的移动端页面模拟进行录制的,实际上在手机上的效果会更好一点:
这个需求的要点主要在以下几点:
- 图片上传后的裁剪,这个需要找到合适的第三方工具,并且支持移动端
- 裁剪完的图片,会作为页面一个img标签进行显示,但还要与其他部分合成为新的图片,这个要借助第三方合成工具
- 图片支持添加文字描述,合成到最后的海报中,同时合成包含若干个区域,需要合理的进行布局以裁剪到正确的部分
框架使用vue,经过前期调研,图片的裁剪可以通过vue-cropper来实现,并且可以完美支持移动端;图片合成,这个因为之前pc端的项目也有用到类似的,通过html2canvas可以截取dom中的某一区域以生成图片,经过调研,也是可以支持移动端的;剩下的布局与区域问题,分析都可以通过代码解决,ok开搞
裁剪功能vue-cropper
关于vue-cropper不必详细介绍了,百度可以查到其用法,设置属性绑定到一个option对象中:
option: {
img: '', // 裁剪图片的地址。可以有三种形式:url 地址 || base64 || blob
size: 1, // 裁剪生成图片的质量, 默认:1, 参数范围:0.1 - 1。
outputType: 'png', // 裁剪生成图片的格式 默认: jpg (jpg 需要传入jpeg) 可选参数:jpeg || png || webp
autoCrop: true, // 是否默认生成截图框.默认为: false
canScale: true, // 图片是否允许滚轮缩放 默认;true 可选:true || false
high: true, // 是否按照设备的dpr 输出等比例图片
fixed: true, // 是否开启截图框宽高固定比例。默认:true
fixedNumber: [224, 242], // 截图框的宽高比例
full: true, // 是否输出原图比例的截图(决定了裁剪图片的画面质量)。
}
这里几乎都是默认值,只有fixedNumber长宽比设置的为裁剪后填入容器的实际长宽比,这样裁剪区域的大小就会根据这个等比例缩放,从而避免图片出现被拉伸变形的情况
截取完毕后,当点击ok按钮时,需要将vue-cropper截取后的图片填充到img中,大部分百度查到的vue-cropper是直接上传到服务器的,实际上也可以将获取到的blob数据填充到容器中,如下:
ok () {
this.showIndex = 0
this.isShowCutReult = true
this.isGenerateAllowed = true
this.$nextTick(() => {
this.$refs.cropper.getCropBlob(async (data) => {
var a = new FileReader();
a.readAsDataURL(data);//读取文件保存在result中
a.onload = function (e) {
var getRes = e.target.result;//读取的结果在result中
var img = document.getElementsByClassName('cut-img-detail')[0]
img.src = getRes
}
});
})
}
合成海报功能html2canvas
之前在pc项目上用过html2canvas,将dom某一个部分合成为一张图片,进行下载。这里我们合成图片后,则需要导出到最终海报img中,先来看看我们页面的整体结构思路:
<template>
<div class="create">
<div class