zoukankan      html  css  js  c++  java
  • vue的图片裁剪上传vue-cropper

    vue-cropper官网

    链接:https://github.com/xyxiao001/vue-cropper

    安装:npm install vue-cropper 或者 yarn add vue-cropper

    组件封装CropperImage.vue

    <template>
      <div class="cropper-content">
        <div class="cropper-box">
          <div class="cropper">
            <vue-cropper
                ref="cropper"
                :img="option.img"
                :outputSize="option.outputSize"
                :outputType="option.outputType"
                :info="option.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="option.infoTrue"
                :maxImgSize="option.maxImgSize"
                :enlarge="option.enlarge"
                :mode="option.mode"
                @realTime="realTime"
                @imgLoad="imgLoad">
            </vue-cropper>
          </div>
          <!--底部操作工具按钮-->
          <div class="footer-btn">
            <div class="scope-btn">
              <label class="btn" for="uploads">选择封面</label>
              <input type="file" id="uploads" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="selectImg($event)">
              <el-button size="mini" type="danger" plain icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
              <el-button size="mini" type="danger" plain icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</el-button>
              <el-button size="mini" type="danger" plain @click="rotateLeft">↺ 左旋转</el-button>
              <el-button size="mini" type="danger" plain @click="rotateRight">↻ 右旋转</el-button>
            </div>
            <div class="upload-btn">
              <el-button size="mini" type="success" @click="uploadImg('blob')">上传封面 <i class="el-icon-upload"></i></el-button>
            </div>
          </div>
        </div>
        <!--预览效果图-->
        <div class="show-preview">
          <div :style="previews.div" class="preview">
            <img :src="previews.url" :style="previews.img">
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import { VueCropper } from 'vue-cropper'
    import {
      showOneMinuteDetails,
      updateOneMinute,
      getuploadImage,
      addOneMinute,
    } from "@/api/table";
    export default {
      name: "CropperImage",
      components: {
        VueCropper
      },
      props:['Name'],
      data() {
        return {
          name:this.Name,
          previews: {},
          option:{
            img: '',             //裁剪图片的地址
            outputSize: 1,       //裁剪生成图片的质量(可选0.1 - 1)
            outputType: 'jpeg',  //裁剪生成图片的格式(jpeg || png || webp)
            info: true,          //图片大小信息
            canScale: true,      //图片是否允许滚轮缩放
            autoCrop: true,      //是否默认生成截图框
            autoCropWidth: 365,  //默认生成截图框宽度
            autoCropHeight: 200, //默认生成截图框高度
            fixed: true,         //是否开启截图框宽高固定比例
            fixedNumber: [1.53, 1], //截图框的宽高比例
            full: false,         //false按原比例裁切图片,不失真
            fixedBox: true,      //固定截图框大小,不允许改变
            canMove: false,      //上传图片是否可以移动
            canMoveBox: true,    //截图框能否拖动
            original: false,     //上传图片按照原始比例渲染
            centerBox: false,    //截图框是否被限制在图片里面
            height: true,        //是否按照设备的dpr 输出等比例图片
            infoTrue: false,     //true为展示真实输出图片宽高,false展示看到的截图框宽高
            maxImgSize: 3000,    //限制图片最大宽度和高度
            enlarge: 1,          //图片根据截图框输出比例倍数
            mode: '230px 150px'  //图片默认渲染方式
          }
        };
      },
      methods: {
        //初始化函数
        imgLoad (msg) {
          console.log("工具初始化函数====="+msg)
        },
        //图片缩放
        changeScale (num) {
          num = num || 1
          this.$refs.cropper.changeScale(num)
        },
        //向左旋转
        rotateLeft () {
          this.$refs.cropper.rotateLeft()
        },
        //向右旋转
        rotateRight () {
          this.$refs.cropper.rotateRight()
        },
        //实时预览函数
        realTime (data) {
          this.previews = data
        },
        //选择图片
        selectImg (e) {
          let file = e.target.files[0]
          console.log(file)
          
          if (!/.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) {
            this.$message({
              message: '图片类型要求:jpeg、jpg、png',
              type: "error"
            });
            return false
          }
          //转化为blob
          let reader = new FileReader()
          reader.onload = (e) => {
            let data
            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
          console.log(this.option)
          reader.readAsDataURL(file)
        },
        //上传图片
        uploadImg (type) {
          let _this = this;
          if (type === 'blob') {
            //获取截图的blob数据
            this.$refs.cropper.getCropBlob(async (data) => {
              let formData = new FormData();
              formData.append('file',data,"DX.jpg")
              //调用axios上传
              getuploadImage(formData, {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          })
            .then((res) => {
              console.log(res)
              
               _this.$emit('uploadImgSuccess',res.data.data);
               this.option.img=""
            })
            .catch((err) => {
              this.$message.warning("出现未知问题,刷新页面,或者联系程序员");
            });
            })
          }
        },
      },
    }
    </script>
    
    <style scoped lang="scss">
    .cropper-content{
      z-index: 9999;
      display: flex;
      display: -webkit-flex;
      justify-content: flex-end;
      .cropper-box{
        flex: 1;
         100%;
        .cropper{
           auto;
          height: 300px;
        }
      }
    
      .show-preview{
        flex: 1;
        -webkit-flex: 1;
        display: flex;
        display: -webkit-flex;
        justify-content: center;
        .preview{
          overflow: hidden;
          border:1px solid #67c23a;
          background: #cccccc;
        }
      }
    }
    .footer-btn{
      margin-top: 30px;
      display: flex;
      display: -webkit-flex;
      justify-content: flex-end;
      .scope-btn{
        display: flex;
        display: -webkit-flex;
        justify-content: space-between;
        padding-right: 10px;
      }
      .upload-btn{
        flex: 1;
        -webkit-flex: 1;
        display: flex;
        display: -webkit-flex;
        justify-content: center;
      }
      .btn {
        outline: none;
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        -webkit-appearance: none;
        text-align: center;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        outline: 0;
        -webkit-transition: .1s;
        transition: .1s;
        font-weight: 500;
        padding: 8px 15px;
        font-size: 12px;
        border-radius: 3px;
        color: #fff;
        background-color: #409EFF;
        border-color: #409EFF;
        margin-right: 10px;
      }
    }
    </style>

    Tailoring.vue:

    <template>
      <div class="cropper-app">
        <el-form :model="formValidate" :rules="ruleValidate" ref="formValidate" label-width="100px" class="demo-ruleForm">
          <el-form-item label="封面上传" prop="mainImage">
            <div class="list-img-box">
              <div v-if="formValidate.mainImage !== ''">
                <img :src="formValidate.mainImage" style='300px;height:150px' alt="自定义封面">
              </div>
              <div v-else class="upload-btn" style="height: 120px;" @click="uploadPicture('flagImg')">
                <i class="el-icon-plus" style="font-size: 30px;"></i>
                <span>封面设置</span>
              </div>
            </div>
            <input type="hidden" v-model="formValidate.mainImage" placeholder="请添加封面">
          </el-form-item>
        </el-form>
        <!-- 剪裁组件弹窗 -->
        <el-dialog
            title="裁切封面"
            :visible.sync="cropperModel"
            width="950px"
            center
           >
         <cropper-image
             :Name="cropperName"
             @uploadImgSuccess = "handleUploadSuccess"
             ref="child">
         </cropper-image>
        </el-dialog>
        <!--查看大封面-->
        <el-dialog
            title="查看大封面"
            :visible.sync="imgVisible"
            center>
          <img :src="imgName" v-if="imgVisible" style=" 100%" alt="查看">
        </el-dialog>
      </div>
    </template>
    
    <script>
    import CropperImage from "@/views/resmanage/CropperImage";
    export default {
      name: "Tailoring",
      components: {CropperImage},
      data () {
        return {
          formValidate: {
            mainImage: '',
          },
          ruleValidate: {
            mainImage: [
              {required: true, message: '请上传封面', trigger: 'blur'}
            ],
          },
          //裁切图片参数
          cropperModel:false,
          cropperName:'',
          imgName: '',
          imgVisible: false
        }
      },
      methods: {
        //封面设置
        uploadPicture(name){
          this.cropperName = name;
          this.cropperModel = true;
        },
        //图片上传成功后
        handleUploadSuccess (data){
          console.log(data)this.cropperModel = false;
        }
      }
    }
    </script>
    <style scoped>
      .upload-list-cover{
          position: absolute;
          top: 0;
          bottom: 0;
          left: 0;
          right: 0;
          display: flex;
          flex-wrap: wrap;
          justify-content: space-between;
          padding: 0 40px;
          align-items: center;
          background: rgba(0,0,0,.6);
          opacity: 0;
          transition: opacity 1s;
      }
      .cover_icon {
        font-size: 30px;
      }
      .upload-btn{
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -ms-flex-wrap: wrap;
        flex-wrap: wrap;
        -webkit-box-pack: center;
        -ms-flex-pack: center;
        justify-content: center;
        -webkit-box-align: center;
        -ms-flex-align: center;
        align-items: center;
        border: 1px solid #cccccc;
        border-radius: 5px;
        overflow: hidden;
        box-shadow: 0 0 1px #cccccc;
      }
      .upload-btn:hover {
        border: 1px solid #69b7ed;
      }
      .upload-btn i{
        margin: 5px;
      }
    </style>

    转载:https://blog.csdn.net/qq_41107231/article/details/109725839

  • 相关阅读:
    C. Mobile phones
    star
    敌兵不正
    Java数据类型
    Eclipse的使用及Java程序的标识符和关键字
    Python学习笔记字符串操作之小结之表格打印
    HTML学习笔记7----图像
    Python学习笔记字符串操作之小结之Wiki标记中添加无序列表
    Python学习笔记字符串操作之pyperclip模块拷贝粘贴字符串
    Python学习笔记字符串操作之strip()、rstrip()和lstrip()方法删除空白格
  • 原文地址:https://www.cnblogs.com/xiaobaibubai/p/15047518.html
Copyright © 2011-2022 走看看