通過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對(duì)象,其中我們還要給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ù)要對(duì)圖片進(jìn)行一些后續(xù)的處理
FileReader對(duì)象 ????
首先我們先了解一下FileReader這個(gè)對(duì)象
簡單的來講就是FileReader這個(gè)對(duì)象允許應(yīng)用程序異步的讀取計(jì)算機(jī)的文件內(nèi)容,其中這個(gè)對(duì)象提供了一些方法,我們等會(huì)會(huì)用到它提供的一些方法。
readAsDataURL(file):讀取文件內(nèi)容,結(jié)果用data:url的字符串形式表示readAsText(file,encoding):按字符讀取文件內(nèi)容,結(jié)果用字符串形式表示readAsArrayBuffer(file):按字節(jié)讀取文件內(nèi)容,結(jié)果用ArrayBuffer對(duì)象表示
// 讀取圖片原始的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 方法的一般流程如下:
- 獲取文件對(duì)象(例如,通過文件選擇框選擇文件)
- 創(chuàng)建一個(gè)
FileReader對(duì)象 (即為new FileReader())。 - 為
FileReader對(duì)象綁定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對(duì)象作為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,所以我們要對(duì)傳遞進(jìn)來的quality/100 - 最后將壓縮的圖片通過setAttribute設(shè)置到src上面。
壓縮前后的圖片進(jìn)行對(duì)比:??♀??♀

大小的改變:


片大小上縮小了3倍。這節(jié)省了空間,在一些顯示圖片很多的網(wǎng)站就可以使用這種壓縮,在頁面展示的時(shí)候可以顯示這種壓縮之后的圖片,當(dāng)點(diǎn)擊進(jìn)去之后可以顯示原本沒有壓縮的圖片,這樣就節(jié)省了很多的性能。
但是壓縮之后的圖片確實(shí)沒有之前美觀,所以這是有舍有得,我們可以在具體的情景中靈活的使用。
總結(jié)????
這次通過對(duì)圖片壓縮的學(xué)習(xí),是自己有了解學(xué)習(xí)了之前所不知道的知識(shí),比如圖片的存儲(chǔ)形式以及FileReader之類的,使自己收獲很多。
以上就是通過JavaScript實(shí)現(xiàn)圖片壓縮的詳細(xì)內(nèi)容,更多關(guān)于JavaScript壓縮圖片的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS中獲取函數(shù)調(diào)用鏈所有參數(shù)的方法
這篇文章主要介紹了JS中獲取函數(shù)調(diào)用鏈所有參數(shù)的方法,本文直接給出代碼示例,需要的朋友可以參考下2015-05-05
利用JavaScript控制元素(標(biāo)簽)的顯示與隱藏
這篇文章主要給大家介紹了關(guān)于如何利用JavaScript控制元素(標(biāo)簽)的顯示與隱藏的相關(guān)資料,JavaScript有多種方式可以實(shí)現(xiàn),文中介紹了三種方法以及區(qū)別,需要的朋友可以參考下2023-07-07
JS中call(),apply(),bind()函數(shù)的區(qū)別與用法詳解
這篇文章主要介紹了JS中call(),apply(),bind()函數(shù)的高級(jí)用法詳解,需要的朋友可以參考下2022-12-12
javascript+HTML5的Canvas實(shí)現(xiàn)Lab單車動(dòng)畫效果
這篇文章主要介紹了javascript+HTML5的Canvas實(shí)現(xiàn)Lab單車動(dòng)畫效果,涉及javascript使用Canvas配合數(shù)學(xué)運(yùn)算實(shí)現(xiàn)自行車動(dòng)畫效果,需要的朋友可以參考下2015-08-08
前端實(shí)現(xiàn)文件下載的4種常見方式與實(shí)戰(zhàn)示例
在前端開發(fā)中,實(shí)現(xiàn)文件下載是一個(gè)非常常見的需求,本篇文章將介紹 4 種前端文件下載的方式,并提供詳細(xì)示例,希望能幫助大家掌握文件下載的各種技巧2025-04-04
使用BootStrapValidator完成前端輸入驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了使用BootStrapValidator來完成前端輸入驗(yàn)證,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
購物車前端開發(fā)(jQuery和bootstrap3)
針對(duì)購物車的操作,進(jìn)行產(chǎn)品數(shù)量的增加減少,刪除購物車中產(chǎn)品項(xiàng),本文使用JQuery1.11和bootstrap3進(jìn)行購物車開發(fā),感興趣的小伙伴們2016-08-08
JavaScript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)跳轉(zhuǎn)(推薦)
這篇文章主要介紹了JavaScript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)跳轉(zhuǎn)(推薦)的相關(guān)資料,涉及到settimeout和setinterval方法的介紹,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

