最近我司一项目,在个人中心页面上需用户上传个性传封面图(类似知乎个人主页上部),用户上传图片大小不一,且封面图大小为1000px*240px;这就需要在用户上传的时候对图片进行合适大小裁剪。
大概思路:
用户上传图片时
- 判断图片尺寸大小,宽高不能小于1200px240;小于这个尺寸将无法完美裁剪。
- 将图片转化为base64格式,即时回显图片和不浪费服务器资源。
这两步完成后,将进入到vue-cropper的裁剪操作了,具体操作可见文档,我在下面写了我的配置供参考;
vue-cropper地址: https://github.com/xyxiao001/vue-cropper
裁剪操作结束,点击确认,得到裁剪后返回图片对象为blod类型,但服务器只接收file类型,故需转为file类型给服务器;得到服务器图片路径后,替换掉原本图片路径,完成✅
- 下载
npm install vue-cropper
- 配置
我使用的是全局配置,此处只写出全局配置
2.1 在~/plugins文件夹下,新建 cropper.js文件;引入vue-cropper
import vueCropper from 'vue-cropper';
import Vue from 'vue';
Vue.use(vueCropper);
2.2 在~/nuxt.config.js文件中,配置插件
export default{
plugins: [
{ src: '~/plugins/cropper', ssr: false }
]
}
- 使用
template
<div>
<div>
<input v-if="status" id="uploadFileInput" type="file" accept="image/png,image/jpeg" >
</div>
<div class="cropper-content" v-else>
<div class="cropper" style="text-align:center">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:centerBox="option.centerBox"
:infoTrue="option.infoTrue"
:fixedBox="option.fixedBox"
:mode="option.mode">
</vueCropper>
</div>
<div class="btnGroup">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="finish" :loading="loading">确认</el-button>
</div>
</div>
style
.cropper-content{
width: 100%;
height: 300px;
}
.cropper {
width: 100%;
height: 240px;
}
.btnGroup{
float: right;
margin-top: 10px;
margin-right: 15px;
}
script
export default{
data(){
status: true,
option: {
img: '', // 裁剪图片的地址
info: true, // 裁剪框的大小信息
outputSize: 0.8, // 裁剪生成图片的质量
outputType: 'jpeg', // 裁剪生成图片的格式
canScale: true, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 1200, // 默认生成截图框宽度
autoCropHeight: 240, // 默认生成截图框高度
fixedBox: true, // 固定截图框大小 不允许改变
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [25, 6], // 截图框的宽高比例
// full: true, // 是否输出原图比例的截图
canMoveBox: false, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
mode: 'cover', // cover 图片铺满容器
},
},
methods:{
// 触发 input:file
uploadFile() {
try{
this.$refs.upload.querySelector('input').click();
}catch (e) {}
},
// 点击上传按钮后的事件
upload(e) {
let file = e.target.files[0];
var self = this;
this.createReader(file, function (w, h) {
if(w<1200 || h<240){
self.$message.error("请上传宽度大于 1200px,高度大于 240px 的封面图片。");
let UFI = document.getElementById("uploadFileInput");
UFI.value = '';
}else{
self.file2base64(file)
}
})
} ,
// 获取图片宽高
createReader(file, whenReady) {
var reader = new FileReader;
reader.onload = function (evt) {
var image = new Image();
image.onload = function () {
var width = this.width;
var height = this.height;
if (whenReady) whenReady(width, height);
};
image.src = evt.target.result;
};
reader.readAsDataURL(file);
},
// file类型文件 转base64文件类型
file2base64(file){
var reader = new FileReader();
reader.readAsDataURL(file);
var self = this;
reader.onload = function (e) {
// 图片base64化
let newUrl = this.result; //图片路径
self.$nextTick(() => {
self.pageImage = newUrl;
self.option.img = newUrl;
self.dialogVisible = true
})
}
},
// 点击确定,这一步是可以拿到处理后的地址, 然后上传到服务器
finish() {
this.$refs.cropper.getCropBlob((data) => {
// 将接收到blod文件对象转为file
let file = new File([data], 'proFileCover.jpg',{type: data.type, lastModified: Date.now()});
let params = new FormData();
params.append("image", file);
var self = this;
self.$axios.post("upload_image", params)
.then(res=>{
if(res.data.code == 0){
// 显示图片
self.pageImage = res.data.data;
// 关闭隐藏div,显示图片
self.status = false;
}
})
}
},
}
- 最后
通过上述代码操作,就完成了上传图片裁剪的功能。
有我没写明白的地方请评论、私信或邮箱告知我,
邮箱:manbanzhen@qq.com
欢迎访问: www.ofus.ink
欢迎访问: www.manbanzhen.top
网友评论