JS圖片壓縮的簡單實(shí)現(xiàn)
前言關(guān)于圖片壓縮這一般都是由后端來完成~,但是前端掌握這項(xiàng)技能也是必不可少的。
圖片壓縮思路
我們讀取源圖片之后,利用canvas畫板畫出源圖片,然后利用toDataURL這個(gè)API轉(zhuǎn)換成base64的格式
需要FileReade這個(gè)對(duì)象去reader圖片,并且利用reader.onload這個(gè)監(jiān)聽事件完成圖片壓縮。
源碼
index.html文件
<!DOCTYPE html> <html lang="en"> <head> ? ? <meta charset="UTF-8"> ? ? <meta http-equiv="X-UA-Compatible" content="IE=edge"> ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? <title>Document</title> ? ? <style> ? ? ? ? .hide{ ? ? ? ? ? ? display: none; ? ? ? ? } ? ? ? ? .show{ ? ? ? ? ? ? display: initial; ? ? ? ? } ? ? ? ? .img-preview{ ? ? ? ? ? ? width: 300px; ? ? ? ? } ? ? </style> </head> <body> ? ? <p> ? ? ? ? <input type="file" ?id="imgFileSelector" value="請(qǐng)選擇圖片"> ? ? ? </p>? ? ? <p> ? ? ? ? <img id="originImgPreview" class="img-preview ?hide"> ? ? </p> ? ? <p> ? ? ? ? <img id="compressedImgPreview" class="img-preview hide"> ? ? </p> ? ? <script src="./index.js" type="module" ></script> </body> </html>
因?yàn)閕mg元素既不是塊級(jí)元素也不是行內(nèi)級(jí)元素,所以添加類.show時(shí)需要設(shè)置為display:initial。
index.js文件
//獲取HTML元素 const oImageFileSelector=document.querySelector("#imgFileSelector") const oOriginImgPreview=document.querySelector("#originImgPreview") const oCompressedImgPreview=document.querySelector("#compressedImgPreview") //創(chuàng)建reader對(duì)象 const reader=new FileReader() let imgFile=null let quality=90 let compressedImgSrc="" //構(gòu)建IMG_TYPES表 const IMG_TYPES={ ? ? "image/jpeg":"image/jepg", ? ? "image/png":"image/png", ? ? "image/gif":"image/gif", ? ? "image/jpg":"image/jpg" } function init (){ ? ? bindEvent() } //構(gòu)建綁定事件函數(shù) function bindEvent(){ ? ? oImageFileSelector.addEventListener("change",handleFileSelectorChange,false) } function handleFileSelectorChange(e){ ? ? console.log(1) ? ? imgFile=e.target.files[0] ? ? console.log(imgFile) ? ? //判斷imgFile是否存在并且imgFile的類型是否為IMG_TYPES表中的類型 ? ? if(!imgFile || !IMG_TYPES[imgFile.type] ){ ? ? ? ? alert("請(qǐng)選擇正確格式的圖片") ? ? ? ? setImgFileEmpty() ? ? ? ? return ? ? } ? ? setImgPreview(imgFile) } //初始化imgFile function setImgFileEmpty(){ ? ? oImageFileSelector.value="" ? ? imgFile=null ? ? setPreviewVisible(oOriginImgPreview,false) ? ? setPreviewVisible(oCompressedImgPreview,false) } function setImgPreview(imgFile){ ? ? if( imgFile instanceof File){ ? ? ? ? reader.onload=async ()=>{ ? ? ? ? ? ? const originImgSrc=reader.result ? ? ? ? ? ? const compressedImgSrc=await createCompressedImage({ ? ? ? ? ? ? ? ? imgSrc:originImgSrc, ? ? ? ? ? ? ? ? type:imgFile.type ? ? ? ? ? ? }) ? ? ? ? ? ? console.log(compressedImgSrc) ? ? ? ? ? ? console.log("未壓縮",originImgSrc.length) ? ? ? ? ? ? console.log("壓縮后",compressedImgSrc.length) ? ? ? ? ? ? oOriginImgPreview.src=originImgSrc ? ? ? ? ? ? setPreviewVisible(oOriginImgPreview,true) ? ? ? ? ? ? oCompressedImgPreview.src=compressedImgSrc ? ? ? ? ? ? setPreviewVisible(oCompressedImgPreview,true) ? ? ? ? } ? ? ? ? reader.readAsDataURL(imgFile) ? ? } } function createCompressedImage ({ ? ? imgSrc, ? ? type }){ ? ? const oCan=document.createElement("canvas") ? ? const oImg=document.createElement("img") ? ? const context=oCan.getContext("2d") ? ? oImg.src=imgSrc ? ? //因?yàn)橥ㄟ^onload事件觸發(fā)回調(diào)函數(shù),所以需要Promise的resolve回調(diào)傳回值并接收 ? ? return new Promise((resolve)=>{ ? ? ? ? oImg.onload=()=>{ ? ? ? ? ? ? const imageWidth=oImg.width ? ? ? ? ? ? const imageHeight=oImg.height ? ? ? ? ? ? oCan.width=imageWidth ? ? ? ? ? ? oCan.height=imageHeight ? ? ? ? ? ? //利用canvas的drawImage函數(shù)去畫出源圖像 ? ? ? ? ? ? context.drawImage(oImg,0,0,imageWidth,imageHeight) ? ? ? ? ? ? const compressedImgSrc = doCompress(oCan, type, imgSrc) ? ? ? ? ? ? resolve(compressedImgSrc) ? ? ? ? } ? ? }) } //創(chuàng)建遞歸函數(shù),如果壓縮的文件大小大于源文件就繼續(xù)壓縮 function doCompress (canvas,type,imgSrc){ ? ? compressedImgSrc=canvas.toDataURL(type,quality/100) ? ? if(compressedImgSrc.length >=imgSrc.length && quality>10){ ? ? ? ? quality-=10 ? ? ? ? doCompress(canvas,type,imgSrc) ? ? } ? ? return compressedImgSrc } //是否顯示img元素 function setPreviewVisible (node,visible){ ? ? switch(visible){ ? ? ? ? case true: ? ? ? ? ? ? node.classList.remove("hide") ? ? ? ? ? ? node.classList.add("show") ? ? ? ? ? ? break ? ? ? ? case false: ? ? ? ? ? ? node.classList.remove("show") ? ? ? ? ? ? node.classList.add("hide") ? ? ? ? ? ? break ? ? ? ? default: ? ? ? ? ? ? break ? ? } } init()
需要注意的是,我們是通過oImg.onload來執(zhí)行壓縮代碼的,所以我們需要用Promise的resolve回調(diào)來傳出值,通過async、await來接收值。
到此這篇關(guān)于JS圖片壓縮的簡單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)JS圖片壓縮內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于JavaScript或jQuery實(shí)現(xiàn)網(wǎng)站夜間/高亮模式
這篇文章主要介紹了基于JavaScript或jQuery實(shí)現(xiàn)網(wǎng)站夜間/高亮模式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Javascript繼承機(jī)制的設(shè)計(jì)思想分享
我花了很多時(shí)間,學(xué)習(xí)這個(gè)部分,還做了很多筆記。但是都屬于強(qiáng)行記憶,無法從根本上理解。2011-08-08ionic實(shí)現(xiàn)下拉刷新載入數(shù)據(jù)功能
這篇文章主要為大家詳細(xì)介紹了ionic實(shí)現(xiàn)下拉刷新載入數(shù)據(jù)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05微信小程序獲取手機(jī)號(hào)授權(quán)用戶登錄功能
微信小程序中有許多地方需要用戶注冊(cè)用戶信息的地方,用戶需要填寫手機(jī)號(hào)等,下面小編給大家分享微信小程序獲取手機(jī)號(hào)授權(quán)用戶登錄功能,需要的朋友參考下吧2017-11-11基于微信小程序?qū)崿F(xiàn)人臉數(shù)量檢測(cè)的開發(fā)步驟
最近項(xiàng)目需求是統(tǒng)計(jì)當(dāng)前攝像頭中的人臉個(gè)數(shù),所以下面這篇文章主要給大家介紹了關(guān)于基于微信小程序?qū)崿F(xiàn)人臉數(shù)量檢測(cè)的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12JavaScript實(shí)現(xiàn)打開鏈接頁面的方式匯總
這篇文章主要介紹了JavaScript實(shí)現(xiàn)打開鏈接頁面的方式,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06