• vue中使用图片裁剪cropperjs


    1.引入cropperjs

    在项目中安装cropperjs,npm地址:https://www.npmjs.com/package/cropperjs

    npm install cropperjs
    

    2.封装成组件

    组件中使用到了ant-design-vue中的图标,可自行更换

    组件主代码

    定义了一些属性,并向外暴露出剪裁方法

    <template>
      <div class="cropper-wrapper">
        <div class="img-box">
          <img class="cropper-image" :id="imgId" alt="">
        </div>
        <div class="right-con">
          <div v-if="preview" class="preview-box" :id="previewId"></div>
          <div class="button-box">
            <slot>
              <a-upload action="image/upload" :before-upload="beforeUpload" :showUploadList='false'>
                <a-button style=" 150px;" type="primary">选择本机图片</a-button>
              </a-upload>
            </slot>
            <div v-show="insideSrc" class="operates">
               <a-button type="primary"  icon='redo' title='旋转' @click="rotate" />
               <a-button type="primary"  icon='minus' title='缩小' @click="shrink" />
               <a-button type="primary"  icon='plus' title='放大' @click="magnify" />
               <a-button type="primary"  icon='column-width' title='水平翻转' @click="scale('X')" />
               <a-button type="primary"  icon='column-height' title='垂直翻转' @click="scale('Y')" />
               <a-button type="primary"  icon='arrow-up' title='上移' @click="move(0, -moveStep)" />
               <a-button type="primary"  icon='arrow-left' title='左移' @click="move(-moveStep, 0)" />
               <a-button type="primary"  icon='arrow-down' title='下移' @click="move(0, moveStep)" />
               <a-button type="primary"  icon='arrow-right' title='右移' @click="move(moveStep, 0)" />
    
              <a-button  style=" 150px;margin-top: 10px;" type="primary" @click="crop">{{ cropButtonText }}</a-button >
            </div>
          </div>
        </div>
      </div>
    </template>
    
    <script>
    import Cropper from 'cropperjs'
    import './index.less'
    import 'cropperjs/dist/cropper.min.css'
    export default {
      name: 'Cropper',
      props: {
        src: {
          type: String,
          default: ''
        },
        preview: {
          type: Boolean,
          default: true  //是否显示预览 默认true
        },
        moveStep: {
          type: Number,
          default: 4   //移动一次的大小,默认4
        },
        cropButtonText: {
          type: String,
          default: '裁剪'   //剪裁按钮的文本
        },
        ratio:{
          type: Number,
          default: 5     // 长宽比率,默认5
        }
      },
      data () {
        return {
          cropper: null,
          insideSrc: ''
        }
      },
      computed: {
        imgId () {
          return `cropper${this._uid}`
        },
        previewId () {
          return `cropper_preview${this._uid}`
        }
      },
      watch: {
        src (src) {
          this.replace(src)
        },
        insideSrc (src) {
          this.replace(src)
        }
      },
      methods: {
        beforeUpload (file) {
          const reader = new FileReader()
          reader.readAsDataURL(file)
          reader.onload = (event) => {
            this.insideSrc = event.srcElement.result
          }
          return false
        },
        replace (src) {
          this.cropper.replace(src)
          this.insideSrc = src
        },
        rotate () {
          this.cropper.rotate(90)
        },
        shrink () {
          this.cropper.zoom(-0.1)
        },
        magnify () {
          this.cropper.zoom(0.1)
        },
        scale (d) {
          this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
        },
        move (...argu) {
          this.cropper.move(...argu)
        },
        crop () {
          this.cropper.getCroppedCanvas().toBlob(blob => {
            this.$emit('on-crop', blob)
          })
        }
      },
      mounted () {
        this.$nextTick(() => {
          let dom = document.getElementById(this.imgId)
          this.cropper = new Cropper(dom, {
            preview: `#${this.previewId}`,
            checkCrossOrigin: true,
            aspectRatio: this.ratio,
          })
        })
      }
    }
    </script>
    

    组件用到的less

    .bg{
      background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
    }
    .cropper-wrapper{
       600px;
      height: 340px;
      .img-box{
        height: 340px;
         430px;
        border: 1px solid #ebebeb;
        display: inline-block;
        .bg;
        img{
          max- 100%;
          display: block;
        }
      }
      .right-con{
        display: inline-block;
         170px;
        vertical-align: top;
        box-sizing: border-box;
        padding: 0 10px;
        .preview-box{
          height: 150px !important;
           100% !important;
          overflow: hidden;
          border: 1px solid #ebebeb;
          .bg;
        }
        .button-box{
          padding: 10px 0 0;
          .operates{
            line-height: 0;
            .ant-btn{
               50px;
              height: 32px;
            }
          }
        }
      }
    }
    
    

    3.组件预览

    未选择图片:

    选择一张本机图片后:

    4.使用组件

    首先引入组件,注意位置

    import Cropper from '@/components/Cropper'
    

    在页面中使用组件,并定义了一个剪裁方法

    <cropper :ratio='2' :cropButtonText="'剪裁并提交'"  @on-crop="handleCroped"></cropper>
    

    剪裁处理方法

    handleCroped(blob){
        //将二进制数据放入表单中
        const formData = new FormData()
        formData.append('file', blob)
        //将表单提交到服务器处理 uploadImage 是封装过的上传图片方法
        uploadImage(formData).then((resp) => {
            if(resp.code === 0){
                this.$message.success("上传成功")
                this.$set(this,'image',resp.data)
            }
        })
    },
    

    服务器端处理方法:

    public Result UploadImage()
      {
        var files = HttpContext.Request.Form.Files;
        var file = files[0];
        string imageName = Guid.NewGuid() + ".png";
        string webSite = configuration["webSite"];
        string path = Path.Combine("upload", DateTime.Now.ToString("yyyy-MM-dd"));
        string dir = Path.Combine(env.ContentRootPath,"wwwroot", path);
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        string location = Path.Combine(dir, imageName);
        using (FileStream fs = System.IO.File.Create(location))
        {
            file.CopyTo(fs);
            fs.Flush();
        }
        string url = Path.Combine(webSite , path, imageName);
    
        return Result.Success(url);
    }
    
  • 相关阅读:
    Codeforces Round #371 (Div. 1)
    Making the Grade(POJ3666)
    The trip(Uva 11100)
    Codeforces Round #370 (Div. 2) E. Memory and Casinos (数学&&概率&&线段树)
    [CodeForces
    勾股数组 学习笔记
    NOIP 2015 游记
    BestCoder Round #53 (div.1)
    北大信息学夏令营 游记
    Codeforces Round #313 (Div. 1)
  • 原文地址:https://www.cnblogs.com/xiaoqingtian/p/13720951.html
Copyright © 2020-2023  润新知