小结,整合el-upload和vue-cropper 实现可预览可裁剪的图片上传

  • 安装vue-cropper模块
    npm Install vue-cropper
  • 新建组件,在main.js引入
import uploadAndCropper from "@/components/uploadAndCropper";
Vue.component('uploadAndCropper', uploadAndCropper)
  • 上传图片后显示的图片预览,鼠标悬停后弹出遮罩层,显示裁剪、预览、删除按钮
<span class="uploadBox_imgShow" v-if="fileList.length > 0">
  <img class="image" :src="fileList[0].url">
  <span class="mash">
    <img src="../img/home/cut.png" @click="showCut">
    <img src="../img/home/big.png" @click="handlePictureCardPreview">
    <img src="../img/home/delimg.png" @click="delImg">
  </span>
</span>

部分样式代码

.uploadBox_imgShow{
     
    position: relative;
  }
.uploadBox_imgShow .mash{
     
    position: absolute;
    top: 0;
    left: 0;
    width: 9.375vw;
    height: 9.375vw;
    border-radius: 0.3125vw;
    background: #333333;
    opacity: 0
  }
.uploadBox_imgShow:hover .mash{
     
    opacity: 0.7;
    transition: 0.5s;
  }
  • el-upload部分。auto-upload设为自动上传,裁剪后再上传一次。
<el-upload
  action="/xxx"
  ref="upload"
  list-type="picture-card"
  :before-upload="beforeAvatarUpload"
  :data="{type: dataType}"
  accept=".jpg,.jpeg,.png"
  :on-success="handleAvatarSuccess"
  :on-preview="handlePictureCardPreview"
  :on-exceed ="onExceedFun"
  :file-list="fileList"
  :limit='1'
  :auto-upload="true">
  <i class="el-icon-plus"></i>
  <div slot="tip" class="el-upload__tip" style="font-size: 0.62vw;">{
     {
     tip}}</div>
  <span class="upload_btn">{
     {
     btnMessage}}</span>
</el-upload>
  • 预览图部分
<el-dialog :visible.sync="dialogVisible" v-if="fileList.length>0">
  <img width="100%" :src="fileList[0].url" alt="">
</el-dialog>
  • el-cropper部分
<el-dialog title="图片剪裁" :visible.sync="cropperVisible" append-to-body>
  <div class="cropper-content">
    <div class="cropper" style="text-align:center;width: 100%;height: 500px">
      <vueCropper
        ref="cropper"
        v-if="cropperVisible"
        :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="fixedNumber"
        :centerBox="option.centerBox"
        :infoTrue="option.infoTrue"
        :fixedBox="option.fixedBox"
      ></vueCropper>
    </div>
  </div>
  <div slot="footer" class="dialog-footer">
    <el-button @click="cropperVisible = false">取 消</el-button>
    <el-button type="primary" @click="finish" :loading="loading">确认</el-button>
  </div>
</el-dialog>
  • js部分
import {
     imgupload} from "@/api/home";
export default {
     
    name: "uploadAndCropper",
    data(){
     
      return {
     
        fileInfo: null,
        offOn:false,
        fileName: '',
        dialogVisible: false,
        cropperVisible: false,
        loading: false,
        uploadUrl: '/upload/upload',
        option: {
     
          img: '', // 裁剪图片的地址
          info: true, // 裁剪框的大小信息
          outputSize: 0.8, // 裁剪生成图片的质量
          outputType: 'jpeg', // 裁剪生成图片的格式
          canScale: false, // 图片是否允许滚轮缩放
          autoCrop: true, // 是否默认生成截图框
          // autoCropWidth: 300, // 默认生成截图框宽度
          // autoCropHeight: 200, // 默认生成截图框高度
          fixedBox: false, // 固定截图框大小 不允许改变
          fixed: true, // 是否开启截图框宽高固定比例
          fixedNumber: [5, 5], // 截图框的宽高比例
          full: true, // 是否输出原图比例的截图
          canMoveBox: false, // 截图框能否拖动
          original: false, // 上传图片按照原始比例渲染
          centerBox: true, // 截图框是否被限制在图片里面
          infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        }
      }
    },
    props: {
     
      //图片地址
      fileList: {
     
        type: Array,
        default: () => []
      },
      //图片类型
      dataType: {
     
        type: String
      },
      //按钮上的文字
      btnMessage: {
     
        type: String,
        default: '点击上传图片'
      },
      //上传提示
      tip: {
     
        type: String,
        default: '只能上传jpg/png文件,且不超过2M'
      },
      //裁剪图片宽高比例
      fixedNumber: {
     
        type: Array,
        default: () => [55]
      }
    },
    methods: {
     
      delImg(){
     
        this.$emit('update:fileList', [])
      },
      //自定义上传,裁剪后调用
      async uploadFile(){
     
        if(!this.fileName){
     
          this.fileName = this.fileList[0].url.substring(this.fileList[0].url.lastIndexOf('/')+1)
        }
        const res = await imgupload({
     file: this.fileInfo, fileName: this.fileName, type: this.dataType})
        this.$emit('update:fileList', [{
     url:res.data.data}])
        this.cropperVisible = false
      },
      finish(){
     
        this.$refs.cropper.getCropData((data) => {
     
          this.fileInfo = data
          this.uploadFile()
        })
      },
      beforeAvatarUpload(file) {
     
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isLt2M) {
     
          this.$toast('上传图片大小不能超过 2MB!');
        }
        return isLt2M;
      },
      handlePictureCardPreview(res){
     
        // this.dialogImageUrl = res.url;
        this.dialogVisible = true;
      },
      handleAvatarSuccess(res, file) {
     
        //上传成功
        this.$emit('update:fileList', [{
     url:res.data}])
        this.fileInfo = file//文件
        this.fileName = file.name//文件名
      },
      onExceedFun(){
     
        this.$toast('最多上传1张');
      },
      //显示裁剪框
      showCut(){
     
        this.option.img = this.fileList[0].url
        this.cropperVisible = true
      },
    }
  }
  • 这时,传到后台的图片为base64编码,用sun.misc.CharacterDecoder#decodeBuffer(java.lang.String)解码,输出即可
BASE64Decoder decoder = new BASE64Decoder();
String replace= base64String.replace(" ", "+");
byte[] b = decoder.decodeBuffer(replace);
for (int i = 0; i < b.length; ++i) {
     
	if (b[i] < 0) {
     
		b[i] += 256;
	}
}
OutputStream out = new FileOutputStream(file);
out.write(b);
out.flush();
out.close();
return urlReadResult;

小结,整合el-upload和vue-cropper 实现可预览可裁剪的图片上传_第1张图片

你可能感兴趣的:(vue,java,vue,java)