需求背景
需要从服务器读取图片到页面(图片大小未知),或者上传图片到服务器(图片体积过大,需要压缩) ,此外后端可能能对post请求有设置。
知识罗列:
1.从URL 读取图片信息
2.从本地上传图片
3.前端图片压缩
4.canvas 压缩图片的处理
5.base64转Blob
-Talk is cheap, show me your code
handleChange = async (e, compressRatio = 0.5) => { const file = e.target.files[0]; const { base64file, paddingTop } = await handleFile(file); const { compressedBase64File } = await handleCompressFile( file, compressRatio ); const origin = base64toBlob(base64file); const compress = base64toBlob(compressedBase64File); const originSize = (origin.size / 1000).toFixed(2); const compressSize = (compress.size / 1000).toFixed(2); const compressRate = `${( (originSize - compressSize) / originSize * 100 ).toFixed(2)}%`; return { originStyle: { backgroundImage: `url(${base64file})`, paddingTop }, compressStyle: { backgroundImage: `url(${compressedBase64File})`, paddingTop }, originSize, compressSize, compressRate }; };// 获取原始图片信息handleFile = async file => { const { originFile, base64file, originSize } = await getBase64File(file); const { width, height } = await getImageParams(base64file); const paddingTop = `${height / width * 100}%`; return { originFile, base64file, originSize, width, height, paddingTop }; };// 获取压缩图片信息handleCompressFile = async (file, compressRatio) => { const { base64file } = await getBase64File(file); const { width, height } = await getImageParams(base64file); const targetWidth = width * compressRatio; const targetHeight = height * compressRatio; // 创建Image 对象 const image = new Image(); image.src = base64file; // 创建画布 const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.width = targetWidth; canvas.height = targetHeight; context.fillStyle = "rgba(255,255,255,1)"; context.fillRect(0, 0, targetWidth, targetHeight); context.drawImage(image, 0, 0, targetWidth, targetHeight); const compressedBase64File = canvas.toDataURL("image/jpeg", compressRatio); return { compressedBase64File }; };// file 2 base64getBase64File = file =>new Promise((resolve, reject) => { const reader = new FileReader(); const result = {}; reader.readAsDataURL(file); reader. = () => { result.base64file = reader.result; result.originFile = file; result.originSize = file.size; resolve(result); }; reader. = error => reject(error); });// 通过base64file获取图像尺寸(把base64file换成图片的url,即可通过url获取图片信息,常用来加载cdn的未知图片)getImageParams = base64file =>new Promise((resolve, reject) => { const image = new Image(); image.src = base64file; image. = function() { const width = this.width; const height = this.height; resolve({ width, height }); }; image. = error => reject(error); });// 由于后端post请求的限制 ,可以根据具体情况确定是否 需要把 base64转为 blobbase64toBlob = (base64file, contentType = "image/jpg", sliceSize = 512) => { // 参考 https://stackoverflow.com/questions/16245767/creating-a-blob-from-a-base64-string-in-javascript const byteCharacters = atob(base64file.split(",")[1]); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i += 1) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return new Blob(byteArrays, { type: contentType }); }; $(function() { $("#file").on("change", async function(e) { const { originStyle, compressStyle, originSize, compressSize, compressRate } = await handleChange(e); // 原始图片预览 $(".origin").css({ "padding-top": originStyle.paddingTop, "background-image": originStyle.backgroundImage }); // 压缩图片 $(".compress").css({ "padding-top": compressStyle.paddingTop, "background-image": compressStyle.backgroundImage }); // 信息展示 $(".massage").html(` <div>原始图片大小:${originSize}k</div> <div>压缩图片大小:${compressSize}k</div> <div>压缩比:${compressRate}</div> `); }); });
作者:Null_大大
链接:https://www.jianshu.com/p/6560dc9b6044
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦