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

使用Canvas?API實現(xiàn)前端圖片壓縮功能

 更新時間:2025年08月05日 10:10:54   作者:DawsonT  
這篇文章主要為大家詳細介紹了如何使用Canvas?API實現(xiàn)前端圖片壓縮功能,文章的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習一下

前言

最近我在工作上遇到用戶上傳大尺寸圖片的需求,發(fā)現(xiàn)直接上傳原始圖片會消耗過多帶寬和存儲空間。于是在網(wǎng)上找了一些像 圖片壓縮網(wǎng)站 這樣的工具能在瀏覽器里直接完成壓縮,無需上傳到服務(wù)器,這讓我很受啟發(fā)。經(jīng)過研究,我找到了使用Canvas API的簡單實現(xiàn)方案,下面是自己實現(xiàn)的代碼和想法。

核心實現(xiàn)原理

Canvas圖片壓縮主要利用以下技術(shù)流程:

  • 將原始圖片繪制到Canvas畫布上
  • 調(diào)整Canvas尺寸以實現(xiàn)分辨率壓縮
  • 使用有損編碼(如JPEG)和可調(diào)質(zhì)量參數(shù)輸出圖片
  • 將結(jié)果轉(zhuǎn)換為Blob或Base64格式

關(guān)鍵代碼實現(xiàn)

1. 圖片加載與繪制

function loadImage(file) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    const url = URL.createObjectURL(file);
    
    img.onload = () => {
      URL.revokeObjectURL(url);
      resolve(img);
    };
    
    img.onerror = (e) => {
      reject(e);
    };
    
    img.src = url;
  });
}

2. 核心壓縮函數(shù)

async function compressImage(file, options = {}) {
  const { 
    quality = 0.8, 
    maxWidth = 800, 
    maxHeight = 800,
    mimeType = 'image/jpeg'
  } = options;
  
  // 加載原始圖片
  const img = await loadImage(file);
  
  // 計算縮放比例
  const [newWidth, newHeight] = calculateSize(img, maxWidth, maxHeight);
  
  // 創(chuàng)建canvas并繪制
  const canvas = document.createElement('canvas');
  canvas.width = newWidth;
  canvas.height = newHeight;
  
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0, newWidth, newHeight);
  
  // 轉(zhuǎn)換為Blob對象
  return new Promise((resolve) => {
    canvas.toBlob(
      (blob) => resolve(blob),
      mimeType,
      quality
    );
  });
}

// 輔助函數(shù):計算新尺寸
function calculateSize(img, maxWidth, maxHeight) {
  let width = img.width;
  let height = img.height;
  
  // 計算縮放比例
  if (width > height) {
    if (width > maxWidth) {
      height = Math.round((height * maxWidth) / width);
      width = maxWidth;
    }
  } else {
    if (height > maxHeight) {
      width = Math.round((width * maxHeight) / height);
      height = maxHeight;
    }
  }
  
  return [width, height];
}

3. 使用示例

const fileInput = document.querySelector('input[type="file"]');

fileInput.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  if (!file) return;
  
  try {
    const compressedBlob = await compressImage(file, {
      quality: 0.7,
      maxWidth: 1024,
      maxHeight: 1024
    });
    
    // 使用壓縮后的Blob
    console.log(`原始大小: ${file.size} bytes`);
    console.log(`壓縮后: ${compressedBlob.size} bytes`);
    
    // 可以上傳到服務(wù)器或提供給用戶下載
  } catch (error) {
    console.error('壓縮失敗:', error);
  }
});

關(guān)鍵參數(shù)說明

quality (0-1) : 控制JPEG壓縮質(zhì)量,數(shù)值越小壓縮率越高

maxWidth/maxHeight: 限制圖片最大尺寸,實現(xiàn)分辨率壓縮

mimeType: 可指定為'image/jpeg'(有損)、'image/png'(無損)等

瀏覽器兼容性

Canvas壓縮功能在現(xiàn)代瀏覽器中支持良好,包括:

  • Chrome 50+
  • Firefox 50+
  • Safari 10+
  • Edge 15+

方法補充

使用canvas實現(xiàn)圖片壓縮上傳

實現(xiàn)思路

  • 使用 FileReader 對象獲取本地文件(使用文件選擇 input 元素)的 base64 內(nèi)容
  • 使用 context.drawImage 把獲取到的文件畫在 canvas 上
  • 使用 canvas.toBlob 對圖片做質(zhì)量壓縮

完整代碼

/**
 * 對選中的圖片文件處理
 *
 * @param  {obj}  event  圖片文件
 * */
uploadImg (event) {
    // 為選擇文件返回
    if (!event.target.files[0]) return;
    let file = event.target.files[0],
        fileName = file.name.substring(file.name.lastIndexOf(".") + 1).toLowerCase();
    // 文件格式校驗
    if (fileName != "jpg" && fileName != "png" && fileName != "gif" ) {
        this.$store.commit('setPrompt', {status: true, text: '請選擇正確的圖片格式上傳(jpg,png,gif)'})
        return
    }
    // gif圖片格式不做處理,其他靜態(tài)圖片做質(zhì)量壓縮處理以減小圖片大小
    if (fileName == 'gif') {
        this.uploadApi(file, file.name)
    } else {
        let _this = this;
        // 壓縮圖片需要的一些元素和對象
        let reader = new FileReader(), img = new Image();
        reader.readAsDataURL(file);
        // 縮放圖片需要的canvas
        let canvas = document.createElement('canvas');
        let context = canvas.getContext('2d');
        // base64地址圖片加載完畢后
        img.onload = function() {
            // 圖片原始尺寸
            let originWidth = this.width;
            let originHeight = this.height;
            canvas.width = originWidth;
            canvas.height = originHeight;
            // 清除畫布
            context.clearRect(0, 0, originWidth, originHeight);
            // 圖片壓縮
            context.drawImage(img, 0, 0, originWidth, originHeight);
            // canvas轉(zhuǎn)為blob并上傳
            canvas.toBlob(function(blob) {
                _this.uploadApi(blob, file.name)
            }, file.type == 'image/gif' ? 'image/gif' : "image/jpeg", 0.6);
        }
        // 文件base64化,以便獲知圖片原始尺寸
        reader.onload = function(e) {
            img.src = e.target.result;
        };
    }
},
/**
 * 上傳選中的圖片文件
 *
 * @param  {obj}    file  圖片文件
 * @param  {string} fileName  文件名稱
 * */
uploadApi(file, fileName) {
    let formData = new FormData()
    formData.append('img', file, fileName)
    axios.post('/upload/upload-img', formData, {headers: {'Content-Type': 'multipart/form-data'}}).then((res) => {
        if (res.data.code == 200) {
            this.img_list.splice(this.img_list.length, 1, res.data.url)
        } else {
            this.$store.commit('setPrompt', {status: true, text: res.data.message})
        }
    })
}

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

相關(guān)文章

最新評論