通過JavaScript實(shí)現(xiàn)圖片壓縮
壓縮圖片的原理????????
其實(shí)我們實(shí)現(xiàn)壓縮的本質(zhì)原理是通過使用canvas中的toDataURL
來進(jìn)行圖片的壓縮操作,但是中間需要經(jīng)過一系列的加工處理,下面我將詳細(xì)的講解細(xì)節(jié)的操作:
const init=()=>{ ?const selectPicture = document.querySelector("#selectImg"); ?const originalPreview = document.querySelector("#imgPreview"); ?const compressPreview = document.querySelector("#compressImg"); ?// 綁定點(diǎn)擊事件 ?function BindEvent() { ? ?selectPicture.addEventListener("change", (e) => { ? ? ?const imgFiles = e.target.files[0]; ? ? ?console.log(e.target.files[0]); ? ? ?fn(imgFiles); ? }); } ? ? BindEvent(); ? ?.....剩余內(nèi)容在下面 } init()
- 首先我們創(chuàng)建一個(gè)init函數(shù),我們的代碼都寫在這個(gè)函數(shù)中,并且我們還在里面寫了一個(gè)BindEvent函數(shù),將所有的點(diǎn)擊事件都寫在這個(gè)函數(shù)中,這樣做的目的是使代碼更加的模塊化
- 首先我們要獲取DOM對象,其中我們還要給selectPicture綁定一個(gè)change事件,這個(gè)元素其實(shí)是input type類型為file,當(dāng)我們觸發(fā)事件的時(shí)候會(huì)讓我們選擇一個(gè)圖片資源我們可以通過e.target.files[0]來獲取這個(gè)圖片的屬性包含這個(gè)圖片的名稱(name),類型(type)等
- 緊接著我們要將獲取到的圖片的屬性傳遞給fn這個(gè)函數(shù),這個(gè)函數(shù)要對圖片進(jìn)行一些后續(xù)的處理
FileReader對象 ????
首先我們先了解一下FileReader這個(gè)對象
簡單的來講就是FileReader這個(gè)對象允許應(yīng)用程序異步的讀取計(jì)算機(jī)的文件內(nèi)容,其中這個(gè)對象提供了一些方法,我們等會(huì)會(huì)用到它提供的一些方法。
readAsDataURL(file)
:讀取文件內(nèi)容,結(jié)果用data:url的字符串形式表示readAsText(file,encoding)
:按字符讀取文件內(nèi)容,結(jié)果用字符串形式表示readAsArrayBuffer(file)
:按字節(jié)讀取文件內(nèi)容,結(jié)果用ArrayBuffer對象表示
// 讀取圖片原始的base64 ?const fn = (imgFiles) => { ? ?const render = new FileReader(); ? ?render.readAsDataURL(imgFiles); ? ?render.onload = () => { ? ? ?// console.log(render.result); ? ? ?// 將圖片壓縮處理 ? ? ?originalPreview.setAttribute("src", render.result); ? ? ?imageCompression(render.result, 40, "image/jpg"); ? }; ? ?// 將圖片轉(zhuǎn)化為base64形式 };
在這個(gè)函數(shù)中我們通過調(diào)用readAsDataURL
這個(gè)方法,這個(gè)方法可以用來讀取指定的文件,在讀取完成之后在render上面的 result屬性將包含一個(gè)data:
URL格式的字符串 (base64編碼) 以表示所讀取文件的內(nèi)容。
我們在使用 readAsDataURL
方法的一般流程如下:
- 獲取文件對象(例如,通過文件選擇框選擇文件)
- 創(chuàng)建一個(gè)
FileReader
對象 (即為new FileReader())。 - 為
FileReader
對象綁定onload
事件處理程序,以在文件讀取完成時(shí)執(zhí)行相應(yīng)的操作。 - 調(diào)用
readAsDataURL
方法,將文件作為參數(shù)傳遞給它。 - 在
onload
事件處理程序中,通過result
屬性獲取讀取到的數(shù)據(jù) URL。(這個(gè)數(shù)據(jù)的格式是base64)
我們在這個(gè)函數(shù)中將原始圖片通過setAttribute方法給src屬性設(shè)置值render.result(base64)
在這里我們接下來就需要調(diào)用壓縮圖片的函數(shù)
首先這個(gè)函數(shù)接收三個(gè)值分別是:
imageURL
:圖片的路徑,這里是指處理過的路徑(我們這里是base64格式)quality
:轉(zhuǎn)換之后的圖片質(zhì)量,這里這里取值是(0-100)imageType
:這個(gè)表示圖片的格式(這里的圖片格式就是在Files中的圖片格式 ,也就是通過e.target.files[0]中的圖片格式)
圖片壓縮函數(shù)??♀???♀?
// 壓縮函數(shù) ?const imageCompression = (imageURL, quality, imageType) => { ? ?let canvas = document.createElement("canvas"); ? ?let img = document.createElement("img"); ? ?img.src = imageURL; ? ?img.onload = () => { ? ? ?// 在實(shí)際的工作中,根據(jù)業(yè)務(wù)來計(jì)算相應(yīng)的寬度,這里只是進(jìn)行一個(gè)演示的小demo ? ? ?canvas.width = 300; ? ? ?canvas.height = 300; ? ? ?// 獲取上下文 ? ? ?let ctx = canvas.getContext("2d"); ? ? ?ctx.drawImage(img, 0, 0, 300, 300); ? ? ?// 將圖片壓縮 ? ? ?let compressImage = canvas.toDataURL(imageType, quality / 100); ? ? ?console.log(compressImage); ? ? ?compressPreview.setAttribute("src", compressImage); ? }; };
- 首先在這個(gè)函數(shù)中我們要?jiǎng)?chuàng)建
canvas
元素和一個(gè)img
元素 - 我們要給創(chuàng)建的img元素的src賦值為imgURL,緊接著我們需要給img注冊
onload
方法,確保在img加載完成之后執(zhí)行壓縮操作 - 在加載事件中通過
canvas
創(chuàng)建上下文,這里我們創(chuàng)建一個(gè)2d的上下文(創(chuàng)建一個(gè)CanvasRenderingContext2D
對象作為2D渲染的上下文) - 我們還需要給canvas設(shè)置寬高,當(dāng)然這里我們只是做一個(gè)示例,因此我們的寬高都定義為300,在實(shí)際的開發(fā)中要以真實(shí)的業(yè)務(wù)需求為主。
- 前期工作做完之后我們就通過調(diào)用創(chuàng)建的上下文
ctx
來調(diào)用drawImage將圖片畫在canvas(畫布)上,繪制的起始點(diǎn)是(0, 0)
,繪制后的寬度和高度都被設(shè)置為300
像素。這意味著最終壓縮得到的圖像大小將是300x300
像素。 - 然后我們就要實(shí)現(xiàn)最終的壓縮操作了,通過調(diào)用canvas上的toDataURL方法來實(shí)現(xiàn)壓縮操作,這個(gè)方法接受兩個(gè)參數(shù)
imageType
表示輸出的數(shù)據(jù) URL 的圖像類型(如"image/jpeg"
、"image/png"
等),quality
表示圖像的質(zhì)量,取值范圍為0
到1
,所以我們要對傳遞進(jìn)來的quality/100 - 最后將壓縮的圖片通過setAttribute設(shè)置到src上面。
壓縮前后的圖片進(jìn)行對比:??♀??♀
大小的改變:
片大小上縮小了3倍。這節(jié)省了空間,在一些顯示圖片很多的網(wǎng)站就可以使用這種壓縮,在頁面展示的時(shí)候可以顯示這種壓縮之后的圖片,當(dāng)點(diǎn)擊進(jìn)去之后可以顯示原本沒有壓縮的圖片,這樣就節(jié)省了很多的性能。
但是壓縮之后的圖片確實(shí)沒有之前美觀,所以這是有舍有得,我們可以在具體的情景中靈活的使用。
總結(jié)????
這次通過對圖片壓縮的學(xué)習(xí),是自己有了解學(xué)習(xí)了之前所不知道的知識(shí),比如圖片的存儲(chǔ)形式以及FileReader之類的,使自己收獲很多。
以上就是通過JavaScript實(shí)現(xiàn)圖片壓縮的詳細(xì)內(nèi)容,更多關(guān)于JavaScript壓縮圖片的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信自定義分享鏈接信息(標(biāo)題,圖片和內(nèi)容)實(shí)現(xiàn)過程詳解
這篇文章主要介紹了微信自定義分享鏈接信息(標(biāo)題,圖片和內(nèi)容)實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09Bootstrap基本組件學(xué)習(xí)筆記之面板(14)
這篇文章主要為大家詳細(xì)介紹了Bootstrap基本組件學(xué)習(xí)筆記之面板,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12javascript實(shí)現(xiàn)點(diǎn)擊圖片切換
這篇文章主要介紹了javascript實(shí)現(xiàn)點(diǎn)擊圖片切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04在TypeScript中迭代對象鍵Object.keys不起作用的原因和解決方案
在TypeScript中迭代對象鍵object?keys可能是一場噩夢,以下是我所知道的所有解決方案,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-10-10IE Firefox 使用自定義標(biāo)簽的區(qū)別
IE Firefox 使用自定義標(biāo)簽的區(qū)別,需要的朋友可以參考下。2009-10-10用javascript取得傳遞參數(shù)的個(gè)數(shù)的代碼
用javascript取得傳遞參數(shù)的個(gè)數(shù)的代碼...2007-10-10微信小程序國際化探索實(shí)現(xiàn)(附源碼地址)
這篇文章主要介紹了微信小程序國際化探索實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Express框架Router?Route?Layer對象使用示例詳解
這篇文章主要為大家介紹了Express框架Router?Route?Layer對象使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03