cropperjs图片裁剪器及七牛上传文件

安装:

cropperjs : https://github.com/fengyuanchen/cropperjs
npm install cropperjs --save --save-exact
--save : 成功后存到 package.json 中 dependencies 中
--save-exact : 精确版本号(精确指定版本)

Qiniu-JavaScript-SDK : https://developer.qiniu.com/kodo/1283/javascript
npm install qiniu-js --save --save-exact

package.json 中 dependencies 参数设置
"dependencies": {
    "axios": "0.24.0",
    "cropperjs": "1.5.12",
    "qiniu-js": "3.4.0",
    "vant": "^2.8.1",
    "vue": "^2.5.2",
    "vue-axios": "3.4.0",
    "vue-router": "^3.0.1"
},
执行 npm install

qiniuUpfile.js(上传时显示上传百分比)

import * as qiniu from 'qiniu-js'
import { Toast } from 'vant';

/*
 * 将 base64 图片编码转为 Blob 对象
 * @dataURI 图片 base64 编码
 * @returns {Blob}
 */
const dataURItoBlob = (dataURI) => {
	let byteString = atob(dataURI.split(',')[1]);
	let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
	let ab = new ArrayBuffer(byteString.length);
	let ia = new Uint8Array(ab);
	for (let i = 0; i < byteString.length; i++) {
		ia[i] = byteString.charCodeAt(i);
	}
	return new Blob([ab], {
		type: mimeString
	});
}

export default function(file , token , fileType) {
  if (typeof(file) === 'string') {
  	file = dataURItoBlob(file);
  }
  return new Promise((resolve, reject) => {
    const observable = qiniu.upload(
      file, //file
      'file_' + Math.floor(Math.random() * 1000000000) + '_' + new Date().getTime(), //key
      token, //token
      //putExtra
      {
        // fname: file.name,
        // fname: 'file_',
        // mimeType: [] || null,
        // mimeType: ["image/png", "image/jpeg", "image/gif", 'video/mp4', 'video/mov', 'video/avi', 'video/flv', 'video/mkv', 'video/rmvb', 'video/quicktime'],
        mimeType: fileType ? fileType : null, // "image/jpg" or "video/mp4" or "text/plain" ...
      },
      //config
      {
        useCdnDomain: true, // cdn
        unique_names: false, // 唯一名称
        region: qiniu.region.z0 // 根据区域设置上传的域名
      },
    );
    const subscription = observable.subscribe({
      next(res) {
        // console.log(res);
        Toast.loading({
          duration: 0,
          message: '上传' + parseInt(res.total.percent) + '%',
          forbidClick: true,
        })
      },
      error(err) {
        Toast.clear();
        console.log(err);
        reject(err);
      },
      complete(res) {
        Toast.clear();
        // console.log(res);
        resolve(res);
      }
    })
  });
}

上传图片页面 uploadPicTest.vue
七牛初始化参数数据接口获取
...
this.token = res.data.token;
this.domain = res.data.domain;
...

<template>
  <div>
    <!-- 上传图片 -->
    <div style="width: 100%;height: 642px;position: relative;">
      <div style="width: 6px; height: 100px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <div style="width: 100px; height: 6px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <!-- 结果图片 : 上传七牛云后的图片 -->
      <img v-if="image" :src="image" style="width: 100%;position: relative;" />
      <!-- 上传图片控件 -->
      <input ref="referenceUpload" @change="sendImg" type="file" accept="image/*" style="width: 100%; height: 100%; position: absolute; left: 0; top: 0; opacity: 0;" />
    </div>

    <!-- 编辑上传的图片 -->
    <div v-show="magage" class="pop">
      <div class="pop_body">
        <div class="showimg">
          <!-- 需要编辑的图片 : 上传的图片处理后的base64格式 -->
          <img v-if="magageImg" :src="magageImg" id="image" />
        </div>
        <div>
          <div @click="magage = false" class="base_btn">取消</div>
          <!-- 编辑图片-旋转图片 : 苹果手机如果处理的是相机拍照的图片且较大,则旋转后上传图片失败(空白的图片) -->
          <!-- <div @click="rotateImg" class="base_btn">旋转图片</div> -->
          <div @click="saveImg" class="base_btn">确定</div>
        </div>
      </div>
    </div>

    <!-- 上传文件 -->
    <div class="upfile_controls">
      <div style="width: 6px; height: 100px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <div style="width: 100px; height: 6px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <img v-if="url && filetype == 'img'" :src="url" />
      <img v-if="url && filetype == 'pdf'" src="../assets/img/pdf.png" />
      <input ref="referenceUploadFile" @change="sendFile" type="file" />
    </div>

    <!-- 上传视频 -->
    <div class="upfile_controls" style="width: 400px; height: 300px;">
      <div style="width: 6px; height: 100px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <div style="width: 100px; height: 6px; background-color: #eee; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);"></div>
      <video v-if="upvideo" id="videoID" controls :src="upvideo" @canplaythrough="getVideoTime($event)" preload="auto" x-webkit-airplay="true" webkit-playsinline="true" playsinline="true" x5-playsinline="true"></video>
      <!-- 视频-上传input -->
      <input v-show="!upvideo" ref="referenceUploadVideo" @change="sendVideo" type="file" accept="video/*" />
    </div>

  </div>
</template>

<script>
  import { configQiNui } from '@/api/api.js';
  import 'cropperjs/dist/cropper.css';
  import Cropper from 'cropperjs';
  import qiniuUpFile from '@/api/qiniuUpfile.js';
  export default {
    name: 'Test',
    data() {
      return {
        // 七牛初始化数据
        token : '',
        domain : '',
        /*************************/
        // 上传图片
        image:'', 
        magage:false, // 显示编辑界面
        magageImg:'', //需要编辑的图片 : 上传的图片处理后的base64格式
        cropper:null,
        /*************************/
        // 上传文件
        url:'',
        filetype:'',
        /*************************/
        // 上传视频
        upvideo:''
      }
    },
    created() {
      // 获取七牛初始化数据接口
      configQiNui().then(res=>{
        console.log(res);
        this.token = res.data.token;
        this.domain = res.data.domain;
      }).catch(err=>{
        console.log(err);
      })
    },
    mounted() {

    },
    watch: {

    },
    methods: {
      // 上传base64编码图片到七牛云
      // putb64(pic){
      //   this.$toast.loading({
      //     duration: 0,
      //     message: '处理中...',
      //     forbidClick: true,
      //   })
      //   var url = "https://upload.qiniup.com/putb64/-1";
      //   var xhr = new XMLHttpRequest();
      //   xhr.onreadystatechange = () => {
      //     if (xhr.readyState==4){
      //       let getMsg = JSON.parse(xhr.responseText);
      //       console.log(getMsg);
      //       console.log(this.domain + getMsg.hash);
      //       console.log(this.domain + getMsg.key);
      //       this.image = this.domain + getMsg.key;
      //       this.$nextTick(()=>{
      //         this.$toast.clear();
      //       })
      //     }
      //   }
      //   xhr.open("POST", url, true);
      //   xhr.setRequestHeader("Content-Type", "application/octet-stream");
      //   xhr.setRequestHeader("Authorization", "UpToken " + this.token);
      //   xhr.send(pic);
      // },
      getfileReaderURL(file,callback){
      	var reader = new FileReader();
      	reader.readAsDataURL(file);
        reader.onload=function(e){
      		callback( reader.result);
        }
        reader.onloadend=function(e){}
      },
      // 上传图片-上传图片后相应处理
      sendImg(e){
        if(e.target.files[0]){
          if(e.target.files[0].size / 1024 / 1024 > 5){
            this.$refs.referenceUpload.value = null;
            this.$toast('请上传不超过5M的图片');
            return;
          }
          this.$toast.loading({
            duration: 0,
            message: '上传中...',
            forbidClick: true,
          })
          this.getfileReaderURL(e.target.files[0],(url)=>{
            this.$refs.referenceUpload.value = null;
            // let base64 = url.split(',');
            // this.putb64(base64[1]);
            this.magageImg = url;
            this.magage = true;
            this.$nextTick(()=>{
              if (this.cropper) {
              	this.cropper.destroy();
              }
              const image = document.getElementById('image');
              this.cropper = new Cropper(image, {
                aspectRatio: 7 / 6,
                preview: '.img-preview',
                ready: (e) => {
                  this.$toast.clear();
                  console.log(e.type);
                },
                cropstart: (e) => {
                  console.log(e.type, e.detail.action);
                },
                cropmove: (e) => {
                  console.log(e.type, e.detail.action);
                },
                cropend: (e) => {
                  console.log(e.type, e.detail.action);
                },
                crop: (e) => {
                  var data = e.detail;
                  console.log(e.type);
                },
                zoom: (e) => {
                  console.log(e.type, e.detail.ratio);
                }
              });
            })
          });
        }
      },
      // 编辑图片-旋转图片
      rotateImg(){
      	this.cropper.rotate(45);
      },
      // 确定上传编辑好的图片
      saveImg(){
        let url = this.cropper.getCroppedCanvas({width:700,height:600}).toDataURL('image/jpg');
        // let base64 = url.split(',');
        // this.putb64(base64[1]);
        this.magage = false;
        // 确定上传编辑好的图片至七牛
        qiniuUpFile(url,this.token).then(res=>{
          console.log(res);
          console.log(this.domain + res.hash);
          console.log(this.domain + res.key);
          this.image = this.domain + '/' + res.key;
        }).catch(err=>{
          console.log(err);
        })
      },

      /*************************/

      // 上传文件
      sendFile(e){
        if((e.target.files[0].type == '') || ((e.target.files[0].type.indexOf('image/') == -1) && (e.target.files[0].type.indexOf('/pdf') == -1))){
          this.$toast('请上传图片或PDF格式文件');
          return;
        }
        if(e.target.files[0].type.indexOf('image/') != -1){
          this.filetype = 'img';
        }else{
          this.filetype = 'pdf';
        }
        if(e.target.files[0]){
          if(e.target.files[0].size / 1024 / 1024 > 10){
            this.$refs.referenceUploadFile.value = null;
            this.$toast('请上传不超过10M的文件哦');
            return;
          }
          this.$toast.loading({
            duration: 0,
            message: '上传中...',
            forbidClick: true,
          })
          qiniuUpFile(e.target.files[0],this.token).then(res=>{
            console.log(res);
            console.log(this.domain + res.hash);
            console.log(this.domain + res.key);
            this.$refs.referenceUploadFile.value = null;
            this.url = this.domain + '/' + res.key;
          }).catch(err=>{
            console.log(err);
          })
        }
      },

      /*************************/

      // 上传视频
      sendVideo(e) {
        this.upvideo = '';
        if (e.target.files[0]) {
          if (e.target.files[0].size / 1024 / 1024 > 10) {
            this.$refs.referenceUploadVideo.value = null;
            this.$toast('请上传不超过' + 10 + 'M的视频哦');
            return;
          }
          this.$toast.loading({
            duration: 0,
            message: '上传中...',
            forbidClick: true,
          })
          qiniuUpFile(e.target.files[0], this.token, "video/mp4").then(res => {
            // console.log(res);
            // console.log(this.domain + '/' + res.hash);
            // console.log(this.domain + '/' + res.key);
            this.$refs.referenceUploadVideo.value = null;
            this.upvideo = this.domain + '/' + res.key;
          }).catch(err => {
            console.log(err);
          })
        }
      },
      getVideoTime(e) {
        if(e.target.duration < 3 || e.target.duration > 60){
          this.$toast('本视频时间' + e.target.duration + '秒,请上传' + 3 + '秒至' + 60 + '秒以内的视频');
          this.upvideo = '';
        }
      },

    },

  }
</script>

<style scoped>
.pop{ width: 100%; height: 100%; background-color: rgba(0,0,0,.5); position: fixed; left: 0; top: 0; z-index: 1;
  display: flex; justify-content: center; align-items: center;
}
.pop_body{ text-align: center;}
.showimg{ width: 80vw; height: 65vh; position: relative;}
.showimg img{ width: 100%; position: relative;}
.base_btn{ display: inline-block; width: 200px; height: 70px; line-height: 70px; margin: 40px 10px 0 10px; text-align: center; color: #fff; font-size: 36px; border-radius: 45px;
  background: linear-gradient(90deg, #2BC188 0%, #35CE96 100%);
  box-shadow: 0px 3px 16px rgba(92, 255, 208, 0.4);
}

/* 上传文件/视频 */
.upfile_controls{ width: 200px; height: 200px; margin: 30px auto 0 auto; border-radius: 10px; border: #eee solid 2px; overflow: hidden; position: relative;}
.upfile_controls img,.upfile_controls video,.upfile_controls input{ width: 100%; height: 100%; position: absolute; left: 0; top: 0;}
.upfile_controls img{ object-fit: contain;}
.upfile_controls video{ object-fit: contain; background-color: #000;}
.upfile_controls input{ opacity: 0;}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值