/**
|
* 文件转换
|
* @author Tevin
|
*/
|
|
import moment from 'moment';
|
|
export class FileTransform {
|
|
constructor() {
|
this._data = {
|
chunkSize: 20 * 1024,
|
};
|
}
|
|
getChunkSize() {
|
return this._data.chunkSize;
|
}
|
|
setChunkSize() {
|
return this._data.chunkSize;
|
}
|
|
/**
|
* 转换 ObjectURL 为 base64 数据体(用于java通讯)
|
* @param objUrl
|
* @param callback
|
*/
|
transObjUrlToBaseData(objUrl, callback) {
|
this.convertObjectUrlToBlob(objUrl, blob => {
|
this.convertBlobToBase64(blob, base64 => {
|
const mime = base64.split(',')[0].match(/:(.*?);/)[1];
|
const fileName = this._makeFileName(mime);
|
const baseArr = this.splitBase64ToArray(base64);
|
callback && callback({
|
fileName,
|
baseArr,
|
total: baseArr.length,
|
});
|
});
|
});
|
}
|
|
/**
|
* 转换 base64 数据体为 ObjectURL(用于java通讯)
|
* @param baseData
|
* @param callback
|
*/
|
transBaseDataToObjUrl(baseData, callback) {
|
const base64 = baseData.baseArr.join('');
|
this.convertBase64ToFile(base64, baseData.fileName, file => {
|
this.convertFileToObjectUrl(file, objUrl => {
|
callback && callback(objUrl);
|
});
|
});
|
}
|
|
convertBlobToBase64(blob, callback) {
|
const reader = new FileReader();
|
reader.onload = evt => {
|
callback && callback(evt.target.result);
|
};
|
reader.readAsDataURL(blob);
|
}
|
|
convertObjectUrlToBlob(objUrl, callback) {
|
const xhr = new XMLHttpRequest();
|
xhr.open('GET', objUrl, true);
|
xhr.responseType = 'blob';
|
xhr.onload = function () {
|
if (this.status === 200) {
|
callback && callback(this.response);
|
} else {
|
/* eslint-disable prefer-promise-reject-errors */
|
callback && callback(null, { status: this.status });
|
}
|
};
|
xhr.send();
|
}
|
|
convertBase64ToFile(base64, fileName, callback) {
|
const arr = base64.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);
|
}
|
fileName = fileName || this._makeFileName(mime);
|
const file = new File([u8arr], fileName, { type: mime });
|
callback && callback(file);
|
}
|
|
convertFileToObjectUrl(file, callback) {
|
let URLMaker = URL;
|
if (window) {
|
URLMaker = window.URL || window.webkitURL;
|
}
|
const url = URLMaker.createObjectURL(file);
|
callback && callback(url);
|
}
|
|
// 生成文件名
|
_makeFileName(mime) {
|
const curMoment = moment();
|
const name = 'IMG' + curMoment.format('-YYYYMMDD-HHmmss-') +
|
curMoment.format('x').substr(-3) + '-' + parseInt(Math.random() * 10000);
|
const mimeTypes = {
|
'image/jpeg': 'jpg',
|
'image/gif': 'gif',
|
'image/png': 'png',
|
'image/svg+xml': 'svg',
|
'image/webp': 'webp',
|
'image/tiff': 'tif',
|
'text/plain': 'txt',
|
'text/css': 'css',
|
'text/html': 'html',
|
'text/xml': 'xml',
|
'text/javascript': 'js',
|
'application/x-javascript': 'js',
|
'audio/mpeg': 'mp3',
|
'video/mp4': 'mp4',
|
'video/webm': 'webm',
|
'application/zip': 'zip',
|
'application/rar': 'rar',
|
'application/pdf': 'pdf',
|
'application/rtf': 'rtf',
|
};
|
return name + '.' + mimeTypes[mime];
|
}
|
|
splitBase64ToArray(base64) {
|
const count = Math.ceil(base64.length / this._data.chunkSize);
|
if (count === 1) {
|
return [base64];
|
}
|
const array = [];
|
for (let i = 0; i < count; i++) {
|
const chunk = base64.substr(this._data.chunkSize * i, this._data.chunkSize);
|
array.push(chunk);
|
}
|
return array;
|
}
|
|
/**
|
* 读取文件 base64
|
* @param {File} file
|
* @param {Function} callback
|
*/
|
getFileBase64(file, callback) {
|
const reader = new FileReader();
|
reader.onload = () => callback(reader.result);
|
reader.onerror = error => callback(null, error);
|
reader.readAsDataURL(file);
|
}
|
|
}
|
|
export const $fileTrans = new FileTransform();
|