<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          實用技能!如何使用Canvas封裝圖片壓縮功能

          共 8093字,需瀏覽 17分鐘

           ·

          2024-04-11 08:00


                大廠技術(shù)
                    
                  高級前端
                    
                  前端進階
                
                  

          點擊上方  前端下午茶 ,關(guān)注公眾號

          回復(fù) 1 ,加入前端交流群

          作者:愛泡澡的小蘿ト 原文: https://juejin.cn/post/7220310687481495612

          最近在學(xué)習(xí)和工作中遇到這樣一個場景:如何將前端上傳的圖片進行壓縮傳遞給服務(wù)端?因為此前從未了解過圖片壓縮的功能,所以也是帶著好奇進行了一番學(xué)習(xí),那么我的解決思路如下展示

          整體思路

          1. 創(chuàng)建input框?qū)崿F(xiàn)圖片上傳
          2. 將上傳的文件轉(zhuǎn)成base64格式
          3. 前端通過base64進行原始圖片展示,并將此圖片進行壓縮
          4. 將壓縮后的圖片傳給服務(wù)器

          代碼實現(xiàn)

          首先我們要實現(xiàn)input上傳文件并做一些細節(jié)處理,細節(jié)處理要對上傳的文件類型和上傳的文件大小做限制,類型和大小這里我們可以根據(jù)規(guī)則自定義。

                
                <div class="container">
              <input type="file" id="upload" />
          </div>
                
                const ACCEPT = ['image/jpg''image/png''image/jpeg'// 所能接受的類型(自定義)
          const MAXSIZE = 3 * 1024 * 1024 // 上傳圖片大小限制(自定義)
          const MAXSIZE_STR = '3MB'
          const upload = document.getElementById('upload')
          upload.addEventListener('change', (e) => {
              const [file] = e.target.files
              if (!file) return // 上傳文件為空時終止
              const { type: fileType, size: fileSize } = file
              // 類型判斷
              if (!ACCEPT.includes(fileType)) {
                  alert('不支持' + fileType + '文件類型')
                  upload.value = ''
                  return
              }
              // 圖片大小判斷
              if (fileSize > MAXSIZE) {
                  alert(`文件超出${MAXSIZE_STR}限制`)
                  upload.value = ''
                  return
              }
              // 壓縮圖片
              covertImageToBase64(file, (base64Image) =>
                  compress(base64Image, uploadServer)
              )
          })

          當(dāng)所有限制都通過之后,就要將圖片轉(zhuǎn)為base64格式,也就是進入到covertImageToBase64函數(shù),我們來看看這個函數(shù)做了什么

                
                function covertImageToBase64(file, callback{
              let reader = new FileReader()
              reader.readAsDataURL(file) // 讀取二進制數(shù)據(jù),并將其編碼為 base64 的 data url

              // 讀取完成進行下面操作
              reader.addEventListener('load'function (e{
                  const base64Image = reader.result
                  callback && callback(base64Image) // 將讀取到的結(jié)果傳遞給回調(diào)函數(shù)中
                  reader = null
              })
          }

          這里我們要將上傳獲取的_file_進行編碼轉(zhuǎn)換,通過FileReaader[1]構(gòu)造函數(shù)中的 readAsDataURL[2]方法進行轉(zhuǎn)換,將編碼后的格式文件傳遞給回調(diào)函數(shù)中準(zhǔn)備進行壓縮處理

          到這里這里為了方便大家的理解,我做了一個動圖方便觀看效果,樣式比較簡陋??

          31043704d127379d08b9a0924a6eb2d7.webp

          Kapture 2023-04-10 at 15.00.12 (1).gif

          重點的壓縮圖片函數(shù)

          上面的代碼都比較好理解,這里較為復(fù)雜的邏輯就都在covertImageToBase64函數(shù)的的回調(diào)compress中,這個功能也是壓縮圖片中最為核心的部分。

          先擼為敬

                
                function compress(base64Image, callback{
              let maxW = 800 // 圖片最大寬度
              let maxH = 800 // 圖片最大高度
              const image = new Image()
              image.src = base64Image
              document.body.appendChild(image)
              image.addEventListener('load'function (e{
                  let ratio // 圖片壓縮比 
                  let needCompress = false // 是否需要壓縮
                  // 按照比例進行圖片寬高的修改
                  if (image.naturalWidth > maxW ) {
                      needCompress = true
                      ratio = image.naturalWidth / maxW
                      maxH = image.naturalHeight / ratio
                   }
                   if (maxH < image.naturalHeight) {
                      needCompress = true
                      ratio = image.naturalHeight / maxH
                      maxW = image.naturalWidth / ratio
                    }
                   if (!needCompress) {
                      maxH = image.naturalHeight
                      maxW = image.naturalWidth
                    }
                    const canvas = document.createElement('canvas')
                    canvas.setAttribute('id''__compress__')
                    canvas.width = maxW
                    canvas.height = maxH
                    canvas.style.visibility = 'hidden'
                    document.body.appendChild(canvas)
                    const ctx = canvas.getContext('2d')
                    ctx.clearRect(00, maxW, maxH)
                    ctx.drawImage(image, 00, maxW, maxH)
                    const compressImage = canvas.toDataURL('image/png'0.9)
                    callback && callback(compressImage)
                    // console.log(compressImage)
                    canvas.remove()
                  })
          }
          function uploadServer(compressImage{
              console.log(`upload to server ${compressImage}`)
          }

          代碼分析

          當(dāng)我們接收到傳來的base64編碼的圖片時,可以對其進行壓縮,根據(jù)自定義的寬高與圖片實際寬高對比進行比例計算,通過創(chuàng)建canvas元素畫出該圖片,并通過toDataURL[3] 方法將計算寬高后也就是壓縮后的base64返回,傳入回調(diào)中就可以進行服務(wù)器上傳了,那么通過檢驗也是能夠看到圖片確實進行了壓縮

          03d99e1cbc2252ec274096d2e44aa591.webp

          Kapture 2023-04-10 at 15.55.05.gif

          總結(jié)

          要想更好的理解圖片壓縮,還是要把_FileReader_和_canvas_的一些api弄清楚,這樣才會更加容易理解代碼的邏輯,希望這篇文章能夠幫助到各位大佬

          參考資料

          [1]

          https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FFileReader

          [2]

          https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsDataURL: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FFileReader%2FreadAsDataURL

          [3]

          https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/toDataURL: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fzh-CN%2Fdocs%2FWeb%2FAPI%2FHTMLCanvasElement%2FtoDataURL

          最后



          如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我個小忙:

          1. 點個「喜歡」或「在看」,讓更多的人也能看到這篇內(nèi)容

          2. 我組建了個氛圍非常好的前端群,里面有很多前端小伙伴,歡迎加我微信「sherlocked_93」拉你加群,一起交流和學(xué)習(xí)

          3. 關(guān)注公眾號「前端下午茶」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。



          點個喜歡支持我吧,在看就更好了
              
                

          瀏覽 29
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  69成人在线电影 | 操逼导航 | 亚洲 精品一区二区三区 | 亚洲福利在线观看 | 特级西西西西4444级酉西88wwww特 |