欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript前端實現(xiàn)壓縮圖片功能

 更新時間:2020年03月06日 11:34:40   作者:前端吳亦凡  
這篇文章主要介紹了JavaScript前端實現(xiàn)壓縮圖片功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

為什么要前端來壓縮圖片

最近在做一個移動端h5上傳圖片的功能,本來這個功能并不復(fù)雜,只需要將圖片文件通過axios傳到服務(wù)端即可,但是考慮到現(xiàn)在手機(jī)設(shè)配的拍照功能十分強(qiáng)大,隨便一張照片都能動輒五六兆,而服務(wù)端的要求是上傳圖片必須小于兩兆,而且直接傳這么大圖片,帶寬它也受不了,所以前端進(jìn)行壓縮圖片就成了一個必要的環(huán)節(jié)。

壓縮效果

首先介紹下壓縮的大概流程

  • 通過原生的input標(biāo)簽?zāi)玫揭蟼鞯膱D片文件
  • 將圖片文件轉(zhuǎn)化成img元素標(biāo)簽
  • 在canvas上壓縮繪制該HTMLImageElement
  • 將canvas繪制的圖像轉(zhuǎn)成blob文件
  • 最后將該blob文件傳到服務(wù)端
  • 完成!

接下來看下詳細(xì)步驟

考慮到文章和步驟的完整性,所以我會把每個細(xì)節(jié)都寫出來,即使有些東西很基礎(chǔ)。

1.  使用Input標(biāo)簽來獲取圖片文件資源

這一步大家應(yīng)該最熟悉不過了吧,原生input標(biāo)簽,通過設(shè)置 type 屬性為file來讓用戶可以選擇文件,設(shè)置 accept 限制選擇的文件類型,綁定onchange事件,來獲取確認(rèn)選擇后的文件

<input type="file" accept="image/*" />

點擊控件,觸發(fā)焦點,打開文件資源管理器,選中文件并確認(rèn)后,會觸發(fā)change事件,所以可以在change事件的回調(diào)中獲取選中文件,它長這個樣

2. 讀取文件轉(zhuǎn)成img標(biāo)簽元素

拿到圖片文件后,先將其轉(zhuǎn)成HTMLImageElement,也就是普通的img標(biāo)簽,具體要使用 FileReader構(gòu)造函數(shù)。

先new出來一個img和fileReader的實例,通過fileReader的 readAsDataURL這個api,來讀取圖片文件,其返回值是一個編碼后的base64的字符串,然后將這個字符串賦值給img的src屬性上,這樣就完成了圖片文件到 HTMLImageElement的轉(zhuǎn)化。

// 先new一個img和fileReader的實例
const img = new Image()
const reader = new FileReader()// 讀取文件資源
reader.readAsDataURL(file) 
reader.onload = function(e){ 
 img.src = e.target.result
}

轉(zhuǎn)化的HTMLImageElement

3. canvas壓縮,核心步驟

拿到轉(zhuǎn)化后的img元素后,先取出該元素的寬高度,這個寬高度就是實際圖片文件的寬高度。

const { width: originWidth, height: originHeight } = img

然后定義一個最大限度的寬高度,如果超過這個限制寬高度,則進(jìn)行等比例的縮放

 // 最大尺寸限制
 const maxWidth = 1000,maxHeihgt = 1000
 // 需要壓縮的目標(biāo)尺寸
 let targetWidth = originWidth, targetHeight = originHeight
 // 等比例計算超過最大限制時縮放后的圖片尺寸
 if (originWidth > maxWidth || originHeight > maxHeight) {
   if (originWidth / originHeight > 1) {
    // 寬圖片
    targetWidth = maxWidth
    targetHeight = Math.round(maxWidth * (originHeight / originWidth))
   } else {
    // 高圖片
    targetHeight = maxHeight
    targetWidth = Math.round(maxHeight * (originWidth / originHeight))
   }
  }

計算好將要壓縮的尺寸后,創(chuàng)建canvas實例,設(shè)置canvas的寬高度為壓縮計算后的尺寸,并將img繪制到上面

// 創(chuàng)建畫布
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')

// 設(shè)置寬高度為等同于要壓縮圖片的尺寸
 canvas.width = targetWidth
 canvas.height = targetHeight
 context.clearRect(0, 0, targetWidth, targetHeight)
 //將img繪制到畫布上
 context.drawImage(img, 0, 0, targetWidth, targetHeight)

4. 轉(zhuǎn)成blob文件

canvas繪制完成后,就可以使用 toBlob來將圖像轉(zhuǎn)成blob文件了,這個api接受三個入?yún)?/p>

canvas.toBlob(callback, type, encoderOptions);

回調(diào)函數(shù)中可以得到轉(zhuǎn)化后的blob文件,type為要轉(zhuǎn)成的圖片類型,默認(rèn)png。

encoderOptions為當(dāng)設(shè)置的圖片格式為 image/jpeg 或者 image/webp 時用來指定圖片展示質(zhì)量。

所以如果我們只是要壓縮jpg或者webp格式的圖片的話,不需要進(jìn)行第3部的操作,直接使用這個api,然后填入想要的質(zhì)量參數(shù)就可以了。但實際上,我們還是要考慮多種的圖片格式,因此很有必要使用第三部的過程。

轉(zhuǎn)成的blob長這個樣子

5. 將blob上傳,大功告成。

完整的代碼實現(xiàn)

因為整個過程中都存在著異步回調(diào)操作,所以我使用了async,實現(xiàn)異步代碼的同步執(zhí)行

// 壓縮前將file轉(zhuǎn)換成img對象
function readImg(file) {
 return new Promise((resolve, reject) => {
  const img = new Image()
  const reader = new FileReader()
  reader.onload = function(e) {
   img.src = e.target.result
  }
  reader.onerror = function(e) {
   reject(e)
  }
  reader.readAsDataURL(file)
  img.onload = function() {
   resolve(img)
  }
  img.onerror = function(e) {
   reject(e)
  }
 })
}
/**
 * 壓縮圖片
 *@param img 被壓縮的img對象
 * @param type 壓縮后轉(zhuǎn)換的文件類型
 * @param mx 觸發(fā)壓縮的圖片最大寬度限制
 * @param mh 觸發(fā)壓縮的圖片最大高度限制
 */
function compressImg(img, type, mx, mh) {
 return new Promise((resolve, reject) => {
  const canvas = document.createElement('canvas')
  const context = canvas.getContext('2d')
  const { width: originWidth, height: originHeight } = img
  // 最大尺寸限制
  const maxWidth = mx
  const maxHeight = mh
  // 目標(biāo)尺寸
  let targetWidth = originWidth
  let targetHeight = originHeight
  if (originWidth > maxWidth || originHeight > maxHeight) {
   if (originWidth / originHeight > 1) {
    // 寬圖片
    targetWidth = maxWidth
    targetHeight = Math.round(maxWidth * (originHeight / originWidth))
   } else {
    // 高圖片
    targetHeight = maxHeight
    targetWidth = Math.round(maxHeight * (originWidth / originHeight))
   }
  }
  canvas.width = targetWidth
  canvas.height = targetHeight
  context.clearRect(0, 0, targetWidth, targetHeight)
  // 圖片繪制
  context.drawImage(img, 0, 0, targetWidth, targetHeight)
  canvas.toBlob(function(blob) {
   resolve(blob)
  }, type || 'image/png') })
}

大致執(zhí)行過程,具體可根據(jù)需求,自行改動

async function upload(file){
  const img = await readImg(file)
  const blob = await compressImg(img, file.type, 1000, 1000)
  const formData = new FormData()
  formData.append('file', blob, 'xxx.jpg')
  axios.post('http://xxx.com/api',formData)
}
upload(file).catch(e => console.log(e))

到此這篇關(guān)于JavaScript前端實現(xiàn)壓縮圖片功能的文章就介紹到這了,更多相關(guān)JavaScript 壓縮圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 12行javascript代碼繪制一個八卦圖

    12行javascript代碼繪制一個八卦圖

    本文給大家分享的是使用有限的代碼繪制八卦圖,算是考核下自己對于javascript的理解,這里推薦給大家,有需要的小伙伴參考下。
    2015-04-04
  • 一文搞懂TypeScript的安裝、使用、自動編譯的教程

    一文搞懂TypeScript的安裝、使用、自動編譯的教程

    TypeScript 是一種由微軟開發(fā)的開源、跨平臺的編程語言。它是 JavaScript 的超集,最終會被編譯為 JavaScript 代碼,關(guān)于TypeScript的安裝、使用、自動編譯很多朋友不是很清楚,今天抽空給大家普及下,感興趣的朋友一起看看吧
    2021-06-06
  • 微信小程序緩存支持二次開發(fā)封裝實現(xiàn)解析

    微信小程序緩存支持二次開發(fā)封裝實現(xiàn)解析

    這篇文章主要介紹了微信小程序緩存支持二次開發(fā)封裝實現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • javascript form 驗證函數(shù) 彈出對話框形式

    javascript form 驗證函數(shù) 彈出對話框形式

    javascript合法驗證 js數(shù)據(jù)驗證、js email驗證、js url驗證、js長度驗證、js數(shù)字驗證等(彈出對話框形式)
    2009-06-06
  • JavaScript中數(shù)組遍歷方法合集大全

    JavaScript中數(shù)組遍歷方法合集大全

    在JavaScript中數(shù)組遍歷是常見的操作,有多種方法可以實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于JavaScript中數(shù)組遍歷方法合集的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • JavaScript定義類和對象的方法

    JavaScript定義類和對象的方法

    這篇文章主要介紹了JavaScript定義類和對象的方法,分別以函數(shù)方式與Object類方式實現(xiàn),是javascript非常重要的技巧,需要的朋友可以參考下
    2014-11-11
  • javascript獲得服務(wù)器端控件的ID的實現(xiàn)代碼

    javascript獲得服務(wù)器端控件的ID的實現(xiàn)代碼

    javascript獲得服務(wù)器端控件的ID的實現(xiàn)代碼,需要的朋友可以參考下。
    2011-12-12
  • JavaScript預(yù)編譯的基本概念和過程詳解

    JavaScript預(yù)編譯的基本概念和過程詳解

    JavaScript在執(zhí)行代碼前,會進(jìn)行一個預(yù)編譯的過程,這個過程主要用于處理變量和函數(shù)聲明,預(yù)編譯分為全局預(yù)編譯和函數(shù)預(yù)編譯,本文將給大家詳細(xì)的介紹一下JavaScript預(yù)編譯的基本概念和過程,需要的朋友可以參考下
    2024-05-05
  • JSON獲取屬性值方法代碼實例

    JSON獲取屬性值方法代碼實例

    這篇文章主要介紹了JSON獲取屬性值方法代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-06-06
  • 12個非常有創(chuàng)意的JavaScript小游戲

    12個非常有創(chuàng)意的JavaScript小游戲

    JavaScript 在Web開發(fā)過程中已經(jīng)是必不可少的重要分子,他推動著Web的交互性往越來越高的層次發(fā)展,現(xiàn)在的很多Web游戲也基于這類語言開發(fā)。
    2010-03-03

最新評論