使用 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
}
})
})
}