亚洲VA久久久噜噜噜久久-精品国产性色无码av网站-亚洲午夜福利在线观看-小13箩利洗澡无码视频网站,日本特黄特色AAA大片免费,欧美日韩亚洲中文字幕二区,亚洲精品熟女国产

石家莊網(wǎng)站開發(fā) 石家莊網(wǎng)站開發(fā)公司

資訊動(dòng)態(tài)

察而思、思而行、行而后語、知行合一

【前端技術(shù)】JS壓縮圖片的思路

發(fā)布時(shí)間:2024-09-20 熱度:

在開發(fā)中,相信很多人都做過圖片上傳相關(guān)功能。然而,在圖片上傳過程中,文件體積問題常常被忽視。若直接上傳原圖片,可能因體積較大導(dǎo)致上傳速度慢,且前端渲染時(shí)也會(huì)比較遲緩,極大地影響用戶體驗(yàn)。因此,在不影響清晰度的前提下,前端可以在上傳前對(duì)圖片大小體積進(jìn)行壓縮,調(diào)整到合適大小后再進(jìn)行上傳。本文將詳細(xì)介紹前端 JS 如何實(shí)現(xiàn)圖片壓縮,有需要的小伙伴趕緊收藏起來吧!

原理(必看)

簡(jiǎn)而言之:主要利用 canvas 的 drawImage 方法先將圖片繪制為 canvas 圖像,再通過 toDataURL 轉(zhuǎn)化為 DataURL 來存儲(chǔ)圖片鏈接。

drawImage 簡(jiǎn)單介紹

Canvas 2D API 中的 CanvasRenderingContext2D.drawImage () 方法提供了多種在畫布(Canvas)上繪制圖像的方式。

用法可參考:CanvasRenderingContext2D.drawImage () - Web API 接口參考 | MDN (mozilla.org)。

語法如下:

drawImage (image, dx, dy);

drawImage (image, dx, dy, dWidth, dHeight);

drawImage (image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

我們使用第二種語法進(jìn)行繪制,參數(shù)含義如下:

image:要繪制到上下文的元素。

dx:image 的左上角在目標(biāo)畫布上的 X 軸坐標(biāo)。

dy:image 的左上角在目標(biāo)畫布上的 Y 軸坐標(biāo)。

dWidth:image 在目標(biāo)畫布上繪制的寬度,可對(duì)繪制的 image 進(jìn)行縮放。若不指定,繪制時(shí) image 寬度不會(huì)縮放。

dHeight:image 在目標(biāo)畫布上繪制的高度,可對(duì)繪制的 image 進(jìn)行縮放。若不指定,繪制時(shí) image 高度不會(huì)縮放。

簡(jiǎn)單示例

注意:隨意修改圖像尺寸可能導(dǎo)致圖像失真。我們可以先獲取圖像資源的原始尺寸,然后進(jìn)行等比縮放。即當(dāng)確定設(shè)置寬度后,高度要進(jìn)行等比調(diào)整,可依據(jù)交叉相乘積相等的公式進(jìn)行計(jì)算。

例如,如果寬度設(shè)置為 500,那么高度也應(yīng)進(jìn)行等比縮放。公式為:naturalWidth * X = naturalHeight * 500,由此可計(jì)算出高度 X = naturalHeight * 500 /naturalWidth。

以下是代碼示例:

javascript

復(fù)制

var can = document.querySelector('canvas');

var context = can.getContext('2d');

var imgDom = new Image();

imgDom.src = './img.jpg';

imgDom.onload = function () {

    // 注意:圖像繪制時(shí),必須保證資源已經(jīng)加載完成

    console.log('圖片的原始寬度', imgDom.naturalWidth);

    console.log('圖片的原始高度', imgDom.naturalHeight);


    context.drawImage(

        imgDom,

        0, 0,

        500, imgDom.naturalHeight * 500 / imgDom.naturalWidth

    );

};

toDataURL 簡(jiǎn)單介紹

將圖片繪制到 canvas 后,還需將 canvas 轉(zhuǎn)化為 Data URL。轉(zhuǎn)化為 DataURL 后,可以在屏幕上顯示,也可存儲(chǔ)到后端服務(wù)器。使用 canvas 提供的 toDataURL 實(shí)例方法即可。

官方解釋:HTMLCanvasElement.toDataURL () 方法返回一個(gè)包含圖片展示的 data URI。

參考:HTMLCanvasElement.toDataURL () - Web API 接口參考 | MDN (mozilla.org)。

語法:canvas.toDataURL (type, encoderOptions);

其中,type(可選)為圖片格式,默認(rèn)為 image/png;encoderOptions(可選)在指定圖片格式為 image/jpeg 或 image/webp 的情況下,可以從 0 到 1 的區(qū)間內(nèi)選擇圖片的質(zhì)量。若超出取值范圍,將使用默認(rèn)值 0.92,其他參數(shù)會(huì)被忽略。

簡(jiǎn)單示例

javascript

復(fù)制

// 獲取壓縮后的圖片數(shù)據(jù)

can.width = imgDom.naturalWidth;

can.height = imgDom.naturalHeight;


const compressedData = can.toDataURL('image/jpeg', 0.6); // 可調(diào)整質(zhì)量參數(shù)

console.log('compressedData: ', compressedData);

轉(zhuǎn)化后的 DataURL 結(jié)果如下。

實(shí)現(xiàn)

先給出全部代碼,再進(jìn)行解釋。

html

復(fù)制

<!DOCTYPE html>

<html>

<head>

    <title>圖片壓縮上傳</title>

    <meta charset="UTF-8">

</head>

<body>

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

    <button onclick="compressAndUpload()">壓縮并上傳圖片</button>

    <canvas id="canvas" style="display: none;"></canvas>

    <script>

        function compressAndUpload() {

            const fileInput = document.getElementById('fileInput');

            const file = fileInput.files[0];

            if (!file) {

                alert('請(qǐng)先選擇要上傳的圖片');

                return;

            }

            const reader = new FileReader();

            reader.onload = function () {

                const img = new Image();

                img.src = reader.result;

                img.onload = function () {

                    const canvas = document.getElementById('canvas');

                    const ctx = canvas.getContext('2d');

                    const maxWidth = 800; // 設(shè)置最大寬度為 800 像素

                    let width = img.width;

                    let height = img.height;


                    // 判斷是否需要縮放

                    if (width > maxWidth) {

                        height *= maxWidth / width;

                        width = maxWidth;

                    }

                    // 設(shè)置 canvas 的寬高

                    canvas.width = width;

                    canvas.height = height;


                    // 將圖片繪制到 canvas 上

                    ctx.drawImage(img, 0, 0, width, height);

                    // 獲取壓縮后的圖片數(shù)據(jù)

                    const compressedData = canvas.toDataURL('image/jpeg', 0.7); // 可調(diào)整質(zhì)量參數(shù)


                    // 創(chuàng)建一個(gè)新的壓縮后的 File 對(duì)象

                    const compressedFile = dataURItoBlob(compressedData, file.type);

                    compressedFile.lastModifiedDate = file.lastModifiedDate;

                    compressedFile.name = file.name;


                    // 上傳壓縮后的圖片文件

                    uploadImage(compressedFile);

                };

            };

            reader.readAsDataURL(file);

        }


        function dataURItoBlob(dataURI, mimeType) {

            const binary = atob(dataURI.split(',')[1]);

            const array = [];

            for (let i = 0; i < binary.length; i++) {

                array.push(binary.charCodeAt(i));

            }

            return new Blob([new Uint8Array(array)], { type: mimeType });

        }


        function uploadImage(compressedFile) {

            const formData = new FormData();

            formData.append('image', compressedFile);


            fetch('/upload', {

                method: 'POST',

                body: formData

            })

           .then(response => {

                if (response.ok) {

                    console.log('圖片上傳成功');

                } else {

                    console.error('圖片上傳失敗');

                }

            })

           .catch(error => {

                console.error('發(fā)生錯(cuò)誤:', error);

            });

        }

    </script>

</body>

</html>

下面分析關(guān)鍵代碼部分。

首先,初始化一個(gè) reader,它是 FileReader 對(duì)象的實(shí)例。reader.readAsDataURL(file)這行代碼將選擇的文件讀取為 Data URI 格式的字符串。執(zhí)行這行代碼時(shí),F(xiàn)ileReader 對(duì)象會(huì)異步讀取文件數(shù)據(jù),讀取完成后觸發(fā) onload 事件,讀取結(jié)果存儲(chǔ)在 FileReader 對(duì)象的 result 屬性中,格式為 Data URI 字符串。

接著,將讀取出來的 Data URI 字符串賦值給 Image 的 src,等待 img 加載完畢后開始對(duì) img 進(jìn)行壓縮,壓縮方法如上文所示。

然后,設(shè)置最大寬度為 800,判斷當(dāng)前圖片寬度是否大于該值,若大于則進(jìn)行縮放計(jì)算,小于則不進(jìn)行等比縮放計(jì)算。最后將計(jì)算出的值使用 drawImage 繪制到 canvas 上面。

現(xiàn)在,將 canvas 轉(zhuǎn)化成 Data URI 字符串,canvas.toDataURL('image/jpeg', 0.7)這行代碼將 canvas 上繪制的圖像數(shù)據(jù)導(dǎo)出為 JPEG 格式的 Data URI 字符串,并設(shè)置圖像質(zhì)量為 0.7。

之后,創(chuàng)建一個(gè)新的壓縮后的 File 對(duì)象,通過將 Data URI 字符串轉(zhuǎn)化為 Blob 對(duì)象來實(shí)現(xiàn)。

最后,使用 FormData 進(jìn)行上傳即可。

壓縮前后體積對(duì)比

我們看一下壓縮前后體積對(duì)比,壓縮前為 550290,壓縮后為 31523,縮小了十幾倍,壓縮效果非常明顯。

總結(jié)

前端實(shí)現(xiàn)圖片壓縮主要借助 canvas 來完成。實(shí)現(xiàn)思路是先使用 canvas 的 drawImage 方法將圖片繪制為 canvas 圖像,再結(jié)合 toDataURL 轉(zhuǎn)化為 DataURL 進(jìn)行存儲(chǔ)圖片鏈接以及壓縮圖像質(zhì)量。在 toDataURL 中可以調(diào)整圖像質(zhì)量,同時(shí),在壓縮圖像時(shí)要注意等寬高縮放,否則會(huì)導(dǎo)致圖像失真。


聯(lián)系尚武科技
客戶服務(wù)
石家莊APP開發(fā)
400-666-4864
為您提供售前購(gòu)買咨詢、解決方案推薦等1V1服務(wù)!
技術(shù)支持及售后
石家莊APP開發(fā)公司
0311-83796180
為您提供從產(chǎn)品到服務(wù)的全面技術(shù)支持 !
客戶服務(wù)
石家莊小程序開發(fā)
石家莊小程序開發(fā)公司
加我企業(yè)微信
為您提供售前購(gòu)買咨詢、
解決方案推薦等1V1服務(wù)!
石家莊網(wǎng)站建設(shè)公司
咨詢相關(guān)問題或預(yù)約面談,可以通過以下方式與我們聯(lián)系。
石家莊網(wǎng)站制作
在線聯(lián)系:
石家莊Web開發(fā)
石家莊軟件開發(fā)
石家莊軟件開發(fā)公司
ADD/地址:
河北·石家莊
新華區(qū)西三莊大街86號(hào)河北互聯(lián)網(wǎng)大廈B座二層
Copyright ? 2008-2025尚武科技 保留所有權(quán)利。 冀ICP備12011207號(hào)-2 石家莊網(wǎng)站開發(fā)冀公網(wǎng)安備 13010502001294號(hào)《互聯(lián)網(wǎng)平臺(tái)公約協(xié)議》
Copyright ? 2025 www.dldhf.com, Inc. All rights reserved