Springboot+Vue-Cropper实现头像剪切上传效果

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Springboot+Vue-Cropper实现头像剪切上传效果
使⽤Vue-Cropper这⼀组件实现头像上传,供⼤家参考,具体内容如下
效果展⽰
先看⼀下效果吧,如果效果不能满⾜你的需求,就不必再浪费时间往下看了
点击选择图⽚之后
然后再点击上传图⽚就可以上传成功,具体效果和页⾯布局就是这样
前端代码
使⽤先建议详细阅读vue-cropper官⽅⽂档,⾥⾯介绍的很详细,可以根据⾃⼰的需求进⾏修改:
补充⼀点:整个项⽬中使⽤了elelment-ui组件库,使⽤前先导⼊element-ui
关于解释我会在代码中添加注释,毕竟知其然要知其所以然,学习还是得有溯源精神
<template>
<div style="height: 800px;">
<el-tabs v-model="activeName" @tab-click="handleClick" class="tabs">
<el-tab-pane label="个⼈信息" name="first">
</el-tab-pane>
<el-tab-pane label="更换头像" name="second">
<div class="avatar_header">
<span>当前头像</span>
</div>
<div class="avatar_current">
<img :src="currentimg">
</div>
<div class="avatar_select">
<!-- 这⾥这样做是因为
原来的 <input type="file">标签太丑了,可以⾃⼰去尝试⼀下,看看有多丑
所以使⽤button来控制触发input来进⾏选择⽂件
-->
<input type="file" ref="uploads" id="uploads" accept="image/png, image/jpeg, image/gif, image/jpg" hidden @change="setImage($event)"> <el-button type="primary" @click="selectAvatar">选择图⽚</el-button>
<el-button type="success" style="margin-left:100px;" @click="uploadImg('blob')">上传图⽚</el-button>
</div>
<div class="cropper_box">
<div class="avatar_cropper">
<vue-cropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
:outputType="option.outputType"
:info=""
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:full="option.full"
:fixedBox="option.fixedBox"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:height="option.height"
:infoTrue="True"
:maxImgSize="option.maxImgSize"
:enlarge="option.enlarge"
:mode="option.mode"
</vue-cropper>
</div>
<div class="show_preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'margin': '5px'}">
<div :style="previews.div">
<img :src="option.img" :style="previews.img">
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="修改密码" name="third">
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import qs from 'qs'
import { VueCropper } from 'vue-cropper'
export default {
data() {
return {
activeName:'second',
currentimg:this.$store.getters.getAvatar, //这⾥我是将⽤户信息保存在Vuex进⾏管理
previews:{},
option:{
img:'', //裁剪图⽚的地址,
outputSize:1, //裁剪⽣成的图⽚质量可选(0,1,-1)
outputType:'jpeg', //裁剪⽣成图⽚的格式
info:true, //图⽚⼤⼩信息
canScale:true, //是否允许滚轮缩放
autoCrop:true, //是否默认⽣成截图框
autoCropWidth:240,
autoCropHeight:240, //默认⽣成截图框⼤⼩
fixed:true, //是否开启截图框宽⾼固定⽐例
fixedNumber:[1,1], //截图框的宽⾼⽐,
full:false, //按原⽐例裁剪图⽚,不失真
fixedBox:true, //固定截图框⼤⼩,不允许改变
canMove:false, //上传图⽚是否可以移动,
canMoveBox:true, //截图框是否可以拖动
original:false, //上传图⽚按照原始⽐例渲染
centerBox:false, //截图框是否被限制在图⽚⾥⾯
height:true, //是否按照设备的dpr,输出等⽐例图⽚
infoTrue:false, //true为展⽰真实输出图⽚宽⾼,false展⽰看到的截图框宽⾼,
maxImgSize:3000, //限制图⽚最⼤宽度和⾼度
enlarge:1, //图⽚根据截图框输出⽐例倍数
mode:'400px 300px' //图⽚渲染⽅式
}
}
},
methods: {
// 标签页切换调⽤⽅法,不重要!删掉了⼀些不必要的代码
handleClick(){
},
// 选择图⽚调⽤⽅法
selectAvatar(){
this.$refs.uploads.click();
},
// 真正的选择图⽚⽅法,姑且先这么命名吧
setImage(e){
let file = e.target.files[0];
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
// this.$("图⽚类型不正确");
console.log("图⽚类型不正确");
return false;
}
//转化为blob,使⽤blob是为了在页⾯中展⽰上传的那张图⽚
let reader = new FileReader();
// ⽂件读取成功后触发onload⽅法
reader.onload = (e) => {
// 要在页⾯中展⽰,转化为url形式
if(typeof e.target.result === 'object'){
data = window.URL.createObjectURL(new Blob([e.target.result]))
}else{
data = e.target.result
}
this.option.img = data
//转化为base64
}
reader.readAsDataURL(file)
},
realTime(data){
this.previews = data;
},
//初始化函数
imgLoad(msg){
console.log("⼯具初始化函数====="+msg);
},
// 头像上传调⽤⽅法
uploadImg(type){
let _this = this;
if(type === 'blob'){
//获取截图的blob数据类型
this.$refs.cropper.getCropBlob(async (data) => {
let formData = new FormData();
// 发数据传递到后端,注意这⾥请根据⾃⼰的后端逻辑进⾏处理,我是将⽤户名保存在Vuex中,可以直接进⾏命名 formData.append("username",this.$store.getters.getUsername);
formData.append('file',data,this.$store.getters.getUsername+".jpg");
this.axios.post('/updateavatar',formData).then(function(response){
console.log(response);
if(response.data.code == 200){
console.log(response);
_this.currentimg = response.data.data;
_this.$mit('setAvatar',response.data.data); //把新头像重新保存回Vuex
_this.$router.go(0); //刷新⽹页
}
})
})
}
}
},
components:{VueCropper}
};
</script>
<style scoped>
.tab-create{
position: absolute;
right: 80px;
top: 115px;
margin-top: 5px;
z-index: 999;
}
.avatar_header{
width: 100%;
height: 50px;
font-size: 14;
line-height: 50px;
font-weight: 550;
padding-left: 20px;
text-align: left;
}
.avatar_current{
width: 100%;
height: 260px;
text-align: left;
}
.avatar_current img{
height: 240px;
margin-left: 20px;
}
.avatar_select{
text-align: left;
}
.cropper_box{
text-align: left;
position: relative;
}
.avatar_cropper{
margin-top: 40px;
height: 350px;
width: 450px;
display: inline-block;
}
.show_preview{
display: inline-block;
position: absolute;
top:30px;
left: 500px;
}
</style>
后端代码
这⾥先讲述后端的处理逻辑:
1、获取到头像后,会将图⽚保存在云服务器上,这⾥我们设定的⾃⼰的静态⽂件⽬录在D盘,见static_root。

2、然后将图⽚在云服务器上的url保存在后端mysql数据库中。

3、返回给前端上传成功的消息,携带图⽚的url这样就可以通过url访问到这张图⽚,从⽽在前端进⾏显⽰。

Controller层
@ResponseBody
@PostMapping("/updateavatar")
public Result updateAvatar(@RequestParam("username") String username,@RequestParam("file") MultipartFile file) throws IOException { return userService.uploadAvatar(username,file);
}
Service层直接上impl实现
//这是导的⼯具包,需要在pom.xml安装依赖
import cn.hutool.core.io.FileUtil;
//⼀些端⼝信息
@Value("${server.port}")
private String port;
private static final String ip = "http://localhost";
private static final String static_root = "D:/devplatform_files";
@Override
public Result uploadAvatar(String username, MultipartFile file) throws IOException {
//获取原⽂件的名称
String originalFilename = file.getOriginalFilename();
// String rootFilePath = System.getProperty("user.dir")+"/src/main/resources/files/"+originalFilename;
//获取到⽂件路径
String rootFilePath = static_root +"/avatar/"+ originalFilename;
//保存在⽂件中
FileUtil.writeBytes(file.getBytes(),rootFilePath);
//图⽚访问⽤到的url
String avatar = ip+":"+port+"/avatar/"+originalFilename;
try{
//头像信息存⼊数据库
userMapper.updateAvatar(avatar,username);
//⾃⼰封装的Result结果返回类
System.out.println(e);
return Result.fail("上传失败");
}
}
mapper持久层
@Mapper
@Repository
public interface UserMapper{
String getAvatarByUsername(String username);
}
mapper.xml⽂件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd">
<mapper namespace="erMapper">
<update id="updateAvatar">
update user set avatar = #{avatar} where username = #{username}
</update>
</mapper>
关于Result结果类的封装
public class Result {
private int code; //200是正常⾮200表⽰异常
private String msg;
private Object data;
public static Result success(Object data){
return success(200,"操作成功",data);
}
public static Result success(String msg){
return success(200,msg,null);
}
public static Result success(int code, String msg, Object data){
Result r = new Result();
r.setCode(code);
r.setData(data);
r.setMsg(msg);
return r;
}
public static Result fail(String msg){
return fail(400, msg, null);
}
public static Result fail(String msg, Object data){
return fail(400, msg, data);
}
public static Result fail(int code, String msg, Object data){
Result r = new Result();
r.setCode(code);
r.setData(data);
r.setMsg(msg);
return r;
}
public int getCode() {return code;}
public void setCode(int code) {this.code = code;}
public String getMsg() {return msg;}
public void setMsg(String msg) {this.msg = msg;}
public Object getData() {return data;}
public void setData(Object data) {this.data = data;}
}
当图⽚保存在云服务器上后,就可以通过url直接访问到图⽚了,这⾥我本地展⽰这⼀效果,实现了这⼀效果,前端才能够在img 标签中访问到图⽚。

以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档