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-05
Javascript繼承機(jī)制的設(shè)計(jì)思想分享
我花了很多時(shí)間,學(xué)習(xí)這個(gè)部分,還做了很多筆記。但是都屬于強(qiáng)行記憶,無法從根本上理解。2011-08-08
ionic實(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-12
JavaScript實(shí)現(xiàn)打開鏈接頁面的方式匯總
這篇文章主要介紹了JavaScript實(shí)現(xiàn)打開鏈接頁面的方式,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

