前端js實現圖片選擇後進行壓縮,然後轉換Base64或blob進行上傳操作等。

需求描述:

手機端用戶選擇的照片,肯定很大,直接上傳到服務器壓力很大,圖片壓縮,本質上後臺很容易實現,現在需要前端來實現。
用戶選擇圖片後,還能立馬在界面上看到預覽效果

具體的實現過程。

首先是html代碼,重點只需要看<input>標籤

  <div class="upload-wrap">
            <!-- 圖片預覽 -->
            <div class="xl-uploader__preview">
              <div class="xl-uploader__preview-image">
                <van-image height="100%" width="100%" :src="imgSrc" />
              </div>
              <van-icon
                class="xl-uploader__clear"
                color="#13b7f6"
                name="close"
              />
            </div>
            <!-- 本地選擇圖片 -->
            <div class="xl-uploader__upload">
              <van-icon name="photo" size="0.64rem" color="#dcdee0" />
              <input ref="myFileInput" class="xl-uploader__input" type="file" accept="image/jpg, image/jpeg, image/png" @change="uploadImg"></input>
            </div>
            <!-- 手機拍照 -->
            <div class="xl-uploader__upload">
              <van-icon name="photograph" size="0.64rem" color="#dcdee0" />
            </div>
          </div>

其次是css內容:
重點是input標籤的opacity: 0;,以及寬高都是父元素的高度。實現結果是表面上點擊的是外面的div,實際上會觸發input的點擊事件。

.upload-wrap {
  display: flex;
}
.xl-uploader__upload {
  position: relative;
  width: 80px;
  height: 80px;
  background-color: #f7f8fa;
  border-radius: 8px;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 10px;
}
.xl-uploader__input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  cursor: pointer;
  opacity: 0;
}
.xl-uploader__preview {
  margin-right: 10px;
  position: relative;
}
.xl-uploader__preview-image {
  width: 80px;
  height: 80px;
  border-radius: 8px;
  overflow: hidden;
}
.xl-uploader__clear {
  position: absolute;
  top: -8px;
  right: -8px;
  font-size: 18px;
}

最後是js實現過程:

 async uploadImg() {
      try {
        var that = this
        const inputFiles = await this.$refs.myFileInput.files
         if (inputFiles.length > 1) {
          // 最多隻能上傳1張圖片
          return false
        }
        const img = await this.readImg(inputFiles[0])
        const imgSrc = await this.compressImg(img, 1000, 1000)
        console.log(imgSrc)
        // 拿到轉換的base64格式的圖片內容了,接下去就可以去實現其他的操作。譬如作爲字段內容傳遞給後臺等,還可以拿這個imgSrc來賦值給圖片的src來實現圖片查看預覽操作。
      } catch (error) {
        console.log(error)
      }
    },
    /**
     * 將圖片file轉換爲img對象
     */
    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 mx 觸發壓縮的圖片最大寬度限制
    * @param mh 觸發壓縮的圖片最大高度限制
    */
    compressImg(img, mx, mh) {
      return new Promise((resolve, reject) => {
        const canvas = document.createElement('canvas')
        const context = canvas.getContext('2d')
        const { width: originWidth, height: originHeight } = img
        let dataURL = ''
        // 最大尺寸限制
        const maxWidth = mx
        const maxHeight = mh
        // 目標尺寸
        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)
        dataURL = canvas.toDataURL('image/jpeg') // 轉換圖片爲dataURL
        resolve(dataURL)
        // 轉換爲bolb對象
        // canvas.toBlob(function(blob) {
        //   resolve(blob)
        // }, type || 'image/png')
      })
    },

我這裏去掉了圖片格式傳參,也將轉換爲bolb修改爲base64了。因爲實際項目需求。

參考鏈接地址:https://www.jb51.net/article/182078.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章