vue3实现原生上传图片并压缩为base64后,转成二进制文件,实现预览
上传script
interface STATE { imgUrls: Array;}export default { name: "Index", setup() {const state = reactive({ imgUrls: [], // 上传的图片展示列表});/** 选择图片 */const chooseImg = () => { let inputUploadObj: any = document.createElement("input"); inputUploadObj.setAttribute("id", "input_upload_ID"); inputUploadObj.setAttribute("type", "file"); // 添加这个属性,就可以唤起相机的功能 // inputUploadObj.setAttribute("capture", "user"); // 后置摄像头:camcorder 前置摄像头:user // 这里如果不加属性 accept 是 "image/*" 或者 "video/*",就默认打开摄像头,既可以拍照也可以录像 inputUploadObj.setAttribute("accept", "image/*"); inputUploadObj.setAttribute("style", "visibility:hidden"); // 这里将创建的隐式input控件拼接到body的最后面,会增加页面的长度,所以要在适当的时候,移除掉这个隐式创建的input控件 document.body.appendChild(inputUploadObj); // 这里是模拟点击了input控件 inputUploadObj.click(); // console.log(inputUploadObj.files[0]) inputUploadObj.onchange = () => {uploadImg(inputUploadObj.files[0]); }};// 将文件转成img对象const readImg = function (file) { return new Promise((resolve, reject) => {const img = new Image();const reader = new FileReader();reader.onload = function (e: any) { img.src = e.target.result;};reader.onerror = function (e) { reject(e);};reader.readAsDataURL(file);img.onload = function () { resolve(img);};img.onerror = function (e) { reject(e);}; });};/** * 压缩图片 *@param img 被压缩的img对象 * @param type 压缩后转换的文件类型 * @param mx 触发压缩的图片最大宽度限制 * @param mh 触发压缩的图片最大高度限制 */const compressImg = (img, type, mx, mh): any => { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); const { width: originWidth, height: originHeight } = img; // 最大尺寸限制 const maxWidth = mx; const maxHeight = mh; // 目标尺寸 let targetWidth = originWidth; let targetHeight = originHeight; if (originWidth > maxWidth || originHeight > maxHeight) {if (originWidth / originHeight > 1) { // 宽图片 targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth));} else { // 高图片 targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight));} } canvas.width = targetWidth; canvas.height = targetHeight; if (context) {context.clearRect(0, 0, targetWidth, targetHeight);// 图片绘制context.drawImage(img, 0, 0, targetWidth, targetHeight); } return canvas.toDataURL(type || "image/jpeg", 0.5);};// base64 转二进制const dataURLtoFile = (dataurl, filename) => { //将base64转换为文件 var arr = dataurl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n); while (n--) {u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, {type: mime, });}// 随机数const randomNum = ()=>{ var Num=""; for(var i=0;i {const img = await readImg(file);const blob = compressImg(img, file.type, 1000, 1000);state.imgUrls.push({id: randomNum(),src: blob,});let formdata = new FormData();formdata.append("file", dataURLtoFile(blob,"file-"+randomNum()));// 上传图片接口调用 } return {...toRefs(state),chooseImg }}