需求:对本地上传、远程FTP上传和视频截取三种方式的获得图片放入裁剪区进行裁剪
无论哪种方式,都需要得到裁剪图片的文件file,然后通过window.URL.createObjectURL方法取得图片url,最后通过vue-cropper组件裁剪图片产出图片信息
获取图片文件file
1、本地上传通过组件el-upload(element-ui)中的钩子函数获得上传图片的file 2、通过其它方式获得图片url,首先要把url转为图片file 图片url转换为file的方法:包括跨域
export const imgConvert = {
/**
* 图片url获取base64数据(如果是跨域图片需要设置允许跨域)
* @param img
* @param width
* @param height
* @returns {{dataURL: string, type: string}}
*/
getBase64Image(img, width, height) {
let demoCanvas = document.createElement('canvas')
demoCanvas.width = img.width;
demoCanvas.height = img.height;
const ctx = demoCanvas.getContext("2d")
ctx.drawImage(img, 0, 0, width, height);
const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
const dataURL = demoCanvas.toDataURL("image/" + ext);
return {
dataURL: dataURL,
type: "image/" + ext
};
},
/**
* 图片base64 转为blob
* @param base64
* @returns {Blob}
*/
convertBase64UrlToBlob(base64) {
const urlData = base64.dataURL;
const type = base64.type;
const bytes = window.atob(urlData.split(',')[1]); // 去掉url的头,并转换为byte
// 处理异常,将ascii码小于0的转换为大于0
const ab = new ArrayBuffer(bytes.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], {
type: type
});
},
/**
* base64 转为file类型
* @param dataurl
* @param filename
* @returns {File}
*/
dataURLtoFile(dataurl, filename) {
const arr = dataurl.dataURL.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {
type: mime
});
},
//图片类型枚举
imgType: {
base64: 'base64',
blob: 'blob',
file: 'file'
},
/**
* 图片url转化示例(跨域图片需允许跨域访问)
* demo
* >import {imgConvert} from './../../../util/util_file'
* >logImg(){
* let url = 'http://192.168.1.74/image/role/zhengshi/0002/5100/0172/(2)_V23_sc.jpg'
imgConvert.imgProcess(this.showImg, imgConvert.imgType.file, url, '')
* },
* > showImg(data) {
console.log('data', data)
},
* @param callback 回调函数
* @param imgType 图片类型
* @param fileUrl 图片url地址
* @param fileName 图片名称(可为空)
*/
imgProcess(callback, imgType, fileUrl, fileName = '') {
let image = new Image();
// 设置跨域类型
image.setAttribute("crossOrigin", 'anonymous');
// image.setAttribute("crossOrigin", 'undefined');
// 给img加上随机值一部分情况下能解决跨域
image.src = fileUrl + '?timestamp=' + new Date().valueOf();
// image.src = img + '?time=' + new Date().valueOf();
let that = this
image.onload = function () {
const base64 = that.getBase64Image(image, image.width, image.height);
switch (imgType) {
case that.imgType.base64:
return callback(base64)
break
case that.imgType.blob:
const blob = that.convertBase64UrlToBlob(base64);
return callback(blob)
break
case that.imgType.file:
const file = that.dataURLtoFile(base64, fileName);
return callback(file)
break
}
}
}
}
文件file初始化到裁剪区
然后再把上传的图片file初始化到裁剪区
// 上传的图片初始化截图框
setUploadFile(file) {
this.previewsTime = 0;
const windowURL = window.URL || window.webkitURL;
this.option.img = windowURL.createObjectURL(file);
this.originalImg = this.option.img;
},
裁剪区的组件vue-cropper:通过npm安装,插件地址:github.com/xyxiao001/v…
<vueCropper
ref="vuecropper"
v-bind="option"
@realTime="realTime"
@imgLoad="imgLoad"
:img="option.img"
></vueCropper>
处理截取图片信息:用到daycaca包处理截取图片返回base64编码信息
// 截取
handleCrop() {
let cropW = this.$refs.vuecropper.cropW; // 有效的截图框宽度
let cropH = this.$refs.vuecropper.cropH; // 有效的截图框高度
let getCropAxis = this.$refs.vuecropper.getCropAxis(); // 获取截图框基于容器的坐标点
let getImgAxis = this.$refs.vuecropper.getImgAxis(); // 获取图片基于容器的坐标点
let originalImg = document.querySelector(".originalImg");
let ratio = this.ratio;
daycaca.crop(
originalImg,
{
x: (getCropAxis.x1 - getImgAxis.x1) / ratio,
y: (getCropAxis.y1 - getImgAxis.y1) / ratio,
w: cropW / ratio,
h: cropH / ratio
},
data => {
this.fileArr[this.INDEX].src = data;
this.handleCutReseult([this.fileArr[this.INDEX]]);
}
);
},
之后就是把截取用daycaca方法得到的base64编码通过dataURLtoFile()转换为图片file,在调相关的接口信息即可。