/** * 文件转换 * @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();