react项目实现图片截图并上传oss

 使用 Create-React-App 脚手架创建antd开发,并引入react-cropper.js,将生成的截图上传至oss

npm install --save react-cropper

在项目中引入

import CropperDiv from 'react-cropper';
import '../../../node_modules/cropperjs/dist/cropper.css';

上面代码中CropperDiv是可以自己命名的,我用cropperDiv是为了便于查找. 

import React, { Component } from 'react';
// redux
import { connect } from 'react-redux';
import CropperDiv from 'react-cropper';
import "./index.less";
import '../../../node_modules/cropperjs/dist/cropper.css';

class Job extends Component {
  constructor(props) {
    super(props);
    this.state = {
      cropImg: '',//剪裁框里的图片路径
      newImg:'',//剪裁生成的图片
    }
  }
  render() {
    let { cropImg } = this.state,
    return (
      
{ this.cropperFun = cropper }} key={new Date().getTime()} // preview='.cropper-preview' className='cropper_img_usua' autoCrop={false}//自动显示裁剪框 // autoCropArea={.5} //自动剪裁框大小和图片百分比 viewMode={1} //cropper视图模式 0默认没有限制 1剪裁框在图片内 2图片不铺满 3图片铺满 // dragMode={'none'} //cropper拖拽模式 crop产生新裁剪框 move只可移动 none什么也不处理 // zoomable={true} //是否允许放大图像 guides={false} //显示在裁剪框上方的虚线 // background={false} //是否显示背景的马赛克 // rotatable={false} //是否旋转 minCropBoxWidth={500}//剪裁框最小宽度 minCropBoxHeight={50} // responsive={true} //在调整窗口大小的时候重新渲染cropper />
) } } export default Job;

cropper的属性类型如果是Boolean,大多数情况下都是默认为true,如果有特殊要求可自己定义

上边的div(.img_items)是由于项目需求,将input隐藏在img的底层,less为

  .img_items{
    height: 25px;
    padding: 0 10px;
    position: relative;
    >img{
     width: 25px;
     height: 100%;
     position: relative;
    }
    >input{
      position: absolute;
      width: 25px;
      height: 100%;
      top: 0;
      left: 10px;
      right: 10px;
      bottom: 0;
      opacity: 0;
    }
  }

选择本地图片方法

  handleFileChange = (e) => {
    var that = this;
    e.preventDefault();
    let files;
    if (e.dataTransfer) {
      files = e.dataTransfer.files;
    } else if (e.target) {
      files = e.target.files;
    }
    if (files.length > 0) {
      // 验证 files[0] 信息的文件大小
      const fileMaxSize = 10240;
      let fileSize = files[0].size / 1024;
      if (fileSize > fileMaxSize) {
        openNotificationWithIcon("error", "提示", "文件应小于10M", 4);
        return false;
      } else if (fileSize <= 0) {
        openNotificationWithIcon("error", "提示", "空白文件", 4);
        return false;
      }
      //  读取文件img
      const reader = new FileReader();
      reader.onload = (e) => {
        that.setState({
          cropImg: e.target.result
        })
      }
      reader.readAsDataURL(files[0]);
    }
  }

剪裁

  makeImg= () => {
    var sureSrc = this.cropperFun.getCroppedCanvas().toDataURL();
    var styleData = this.cropperFun.getCropBoxData();
    if (!styleData.styleW) {
      openNotificationWithIcon("error", "提示", "请先选择截图区域", 4.5)
      return;
    }
    this.setState({
      newImg:sureSrc
    })
  }

newImg就是剪裁生成的图片

将剪裁好的图片上传至oss

首先引入包

npm install ali-oss --save

将oss相关的方法独立建.js文件 oss.js

import moment from 'moment';
import OSS from 'ali-oss';

export const OssBucket='...'; //你的ossbucket
export const OssEndpoint='...aliyuncs.com'; //你的ossEndpoint
export const OssSchema='http';
export const OssFileUrl=`${OssSchema}://${OssBucket}.${OssEndpoint}`;

// 生成随机数
export function getRandom(len) {
    len = len || 32;
    var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';   
    var maxPos = chars.length;
    var pwd = '';
    for (var i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos));
      }
      return pwd;
}
export const uploadPath = ( fileType,path) => {
  //fileType是文件类型 png,jpg,mp3等
  var quseTime =moment(Date.now()).format('YYYYMMDDHHmmss');
  var r=getRandom(12);
    return `${path}/${quseTime}${r}.${fileType}`
}
export const client = (ossData) => {
    return new OSS({
      accessKeyId: ossData.access_key_id,
      accessKeySecret: ossData.access_key_secret,
      stsToken: ossData.security_token,
      bucket: OssBucket,
      endpoint:OssEndpoint,
      schema:OssSchema,
    });
}

export const UploadToOss = (ossData,path,file,fileType) => {
    const url = uploadPath(fileType,path)
    return new Promise((resolve, reject) => {
      client(ossData).multipartUpload(url, file).then((data) => {
        resolve({...data,result:0});
      }).catch(error => {
        reject(error)
      })
    })
  } 

接着就可以进行oss上传相关操作

下面是将newImg转化为二进制对象,使用promise方法,防止上传时未转化完毕

  beforeUp = () => {
    let sureSrc=this.state.newImg;
    return new Promise((resolve, reject) => {
         var block = sureSrc.split(";");
         var contentType = block[0].split(":")[1]; // "image/jpeg"
         var realData = block[1].split(",")[1]; // In this case "/9j/4AAQSkZJRgABAQEAAAAAAAD/2wBDA...."
         var blob = base64toBlob(realData, contentType);
         var newtestfile = new File([blob], "");
         resolve(newtestfile)
    })
   }

为安全考虑 要从后台获取上传oss相关数据accessKeyId和accessKeySecret和stsToken(keyId和密钥和token)

以下代码中省去获取keyId和密钥部分用resSecret代替其结果

UploadToOss不要忘记从oss.js引入呦!

nextSureImg = (resSecret) => {
    let that = this;
    let sureSrc = that.state.newImg;
    var block = sureSrc.split(".");
    let contentType = block[block.length - 1]; //png或jpg mp3后缀名
    let path='111'//上传到oss的路径
    that.beforeUp().then(resBefore => {
        UploadToOss(resSecret.data, path, resBefore, contentType).then(resOss => {
            if (resOss.result == 0 || resOss.result == '0') {
                let url=`${OssFileUrl}/${resOss.name}`
                console.log(url); //上传后的文件地址
            } else {
                openMessage('error', resOss.message || 'OSS上传失败', 5);
                return
            }
        })
    })
}

 

你可能感兴趣的:(react,cropper,oss,react,截图,阿里云,cropper,oss)