當前位置:首頁 » 網頁前端 » webjs圖片壓縮
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

webjs圖片壓縮

發布時間: 2022-12-21 15:52:35

1. Web圖片的常見壓縮格式

本文簡單介紹幾種常見的圖片格式,對比壓縮率和質量。

PNG是一種非常流行的無損壓縮格式,所有的瀏覽器都支持這種格式。 它提供了卓越的圖像質量,但是通常來說壓縮率較低。

本文將使用PNG圖片作為基準,對比其他有損格式壓縮,檢查圖片質量並對圖片質量進行評分。

雖然PNG格式老,體積大,但它仍然在網路上佔有一席之地,尤其是在一些對畫質要求很高的場景。同時對於邊緣非常銳利的圖像(例如包含文本的圖像),也建議選擇PNG。 對此類圖片,PNG壓縮與其他格式(包括有損壓縮)相比,文本圖像使用PNG實際上具有更高的壓縮率,並且具有更好的質量優勢。

PNG有兩種模式:24位或8位顏色深度。 前者用於表示照片,後者用於文本圖像,單色照片或Logo圖像。 

BMP只是一個圖像的容器,不提供壓縮。 這是一種格式,主要在圖像處理中使用,譬如說Windows裡面的調色板。

BMP的尺寸很容易計算,譬如說解析度是1920x1080p的RGB圖像,整個的存儲空間大約就是1920 x 1080 x 3 ,大約5MB。可以看得出來,BMP文件的大小明顯大於壓縮格式,包括PNG。通常來說,沒有特殊情況,不應在網站上使用BMP圖片,不過實際情況下網站上還是有很多BMP圖像的。

一般來說,如果想要文件更小,就需要花費更多的處理時間來對文件進行編碼,而解碼時間一般來說相差不大。

回顧一下,BMP圖像質量很好,瀏覽器支持廣泛,但是文件尺寸卻非常大。

GIF作為動畫格式非常流行,不管是微信裡面轉發的動圖表情,還是網站上的動圖,都隨處可見,所有的瀏覽器也都支持GIF圖像。

GIF具有無損壓縮和有損壓縮的混合特性。像素表示形式是無損的,但是顏色深度限制為每個像素8位(即每個圖像轉換為256色,原始的圖像如果是RGB格式的,每個像素實際上使用24位來表示的)。這意味著文件將包含較少的顏色(每個文件最多包含256種不同的顏色),但文件體積更小。 這是24位PNG和8位GIF之間的色彩表示的比較。

可以明顯看到GIF圖像有輪廓效應,這是因為GIF無法表示豐富的色彩。

GIF不適合表示照片或任何其他內容豐富的圖片。但是它們對於簡單的徽標,圖標等很有用,因為這些圖片顏色不多,而且純色居多。根據我的經驗,與GIF相比,8位PNG生成的文件更小,所以對於靜態圖片而言,建議採用8bit PNG。

SVG格式比較特殊,與其他格式有很大不同。 SVG圖像存儲的是幾何形狀,而不是每個像素的值。 它的主要優勢是可以無限放大而不會造成質量損失,具體可以看下圖的對比:

SVG文件類型主要用於徽標,但也用於幾何形狀的圖像。 這種文件的主要缺點是:

對於徽標等小圖片,文件大小通常比PNG或WebP大,尤其對於形狀復雜,不規則的logo。在大多數情況下,無法將圖片有效地轉換為SVG(有一些工具說可以做到這一點,但效果並不理想)。

不論視圖大小如何,SVG文件的圖像質量都很高。 所有現代瀏覽器都支持它。

JPEG是網路圖像的王者。 網路上絕大多數的圖像以JPEG格式存儲,具體的份額可以參考下圖:

什麼使JPEG如此流行? JPEG文件對於絕大多數文件通常都很小。 它的壓縮使用有損演算法,通過犧牲人眼不太敏感的區域的質量來最小化大小。

這種方法可顯著減小尺寸,通常不會出現明顯的變形。 我們可以對比下JUNO探測器拍攝的這張木星照片。

原始PNG照片(2MB)   JPEG最好的質量(1MB) JPEG默認的質量

使用JPEG壓縮,我們可以大幅度縮小尺寸(超過90%),而不會造成質量損失。 當我們放大這些圖片時,質量上也沒有很大的損失。

JPEG並不是對於所有圖像都很管用,如前面介紹PNG時所說的,對於具有銳利邊緣和顏色比較少的圖像,JPEG並不是非常管用。常見的例子就是包含文字的圖片,另一個是徽標:

在這幅圖片裡面,JPEG圖像大約2KB(是PNG文件的兩倍),同時放大來看,JPEG對於邊緣的表示並不理想,同時顏色也有失真。失真非常明顯,即使在圖像的未縮放部分上也清晰可見。

JPEG有兩種格式,一種是Baseline JPEG,一種是Progressive JPEG.

兩者之間的視覺差異是載入圖像的方式。 隨著數據的到達,Baseline從上到下載入圖像。 Progressive以非常低的質量一次列印整個圖像,並且隨著數據的到達,圖像得到了改善。 這里是展示差異的動畫:

JPEG之外的世界– WebP

JPEG壓縮可以很好地減小文件大小,不過JPG已經過時了。 如您所知,IT開發的幾年就像外面的一個世紀一樣。 

最近幾年已經有更新的編碼方法(例如mozJPG),但核心思想保持不變。

同時還有其他的格式在圖像質量和文件大小方面都更好(BPG, JPEG 2000, JPEG XR),但因為某些格式受專利保護,無法在網路上廣泛使用。

幸運的是,有一個可供公眾使用的WebP。 目前,這種格式由Google開發並開源,並採用無損和有損壓縮以最小化文件大小。許多現代瀏覽器都支持它,但覆蓋范圍仍然存在差距。 截至2018年8月,全球將近75%的用戶使用支持WebP圖像的瀏覽器瀏覽Web。 WebP圖像的文件大小和質量看起來很有希望。除了壓縮性能出色外,它的最大優勢還在於多功能性。 它可以有損和無損壓縮,具有特定的顏色深度,透明度和動畫效果。 它在所有這些領域中也表現出色。

簡單總結下,對於靜態圖片幾種格式的對比如下:

下一篇介紹下常見的動態格式有哪些。

2. 如何實現JS中圖片壓縮方法

1.這個用PS轉換成JPG或者GIF或png比較大小選用。

3. 怎麼用JavaScript在線壓縮圖片

主要用了兩個html5的 API,一個file,一個canvas,壓縮主要使用cnavas做的,file是讀取文件,之後把壓縮好的照片放入內存,最後內存轉入表單下img.src,隨著表單提交。
照片是自己用單反拍的,5M多,壓縮下面3張分別是600多kb,400多kb,300kb的最後那張失真度很大了,壓縮效率蠻高的。

<!DOCTYPE html>
<html><head> <meta charset="utf-8"/> <title>File API Test</title> <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script> <script type="text/javascript" src="js/JIC.js"></script> <style> #test{ display: none; } </style></head><body><input type="file" id="fileImg" ><form> <img src="" id="test" alt=""></form><script> function handleFileSelect (evt) { // var filebtn = document.getElementById(id); // console.log(filebtn); // var files = filebtn.target.files; // console.log(filebtn.target); // console.log(files); var files = evt.target.files; for (var i = 0, f; f = files[i]; i++) { // Only process image files. if (!f.type.match('image.*')) { continue; } var reader = new FileReader(); // Closure to capture the file information. reader.onload = (function(theFile) { return function(e) { // Render thumbnail. // console.log(evt.target.files[0]); // console.log(e.target); console.log(e.target.result); var i = document.getElementById("test"); i.src = event.target.result; console.log($(i).width()); console.log($(i).height()); $(i).css('width',$(i).width()/10+'px'); //$(i).css('height',$(i).height()/10+'px'); console.log($(i).width()); console.log($(i).height()); var quality = 50; i.src = jic.compress(i,quality).src; console.log(i.src); i.style.display = "block"; }; })(f); // Read in the image file as a data URL. reader.readAsDataURL(f); } } document.getElementById('fileImg').addEventListener('change', handleFileSelect, false);</script></body></html>

var jic = { /** * Receives an Image Object (can be JPG OR PNG) and returns a new Image Object compressed * @param {Image} source_img_obj The source Image Object * @param {Integer} quality The output quality of Image Object * @return {Image} result_image_obj The compressed Image Object */ compress: function(source_img_obj, quality, output_format){ var mime_type = "image/jpeg"; if(output_format!=undefined && output_format=="png"){ mime_type = "image/png"; } var cvs = document.createElement('canvas'); //naturalWidth真實圖片的寬度 cvs.width = source_img_obj.naturalWidth; cvs.height = source_img_obj.naturalHeight; var ctx = cvs.getContext("2d").drawImage(source_img_obj, 0, 0); var newImageData = cvs.toDataURL(mime_type, quality/100); var result_image_obj = new Image(); result_image_obj.src = newImageData; return result_image_obj; }, function ****(***)

4. WEB保存圖片被壓縮了 怎麼處理

壓縮的是圖片質量,不是圖片尺寸。商品詳情頁不需要特別高的質量要求,這塊數字默認是不用更改的。如果實在想存高質量的圖片,可以導出為tif格式。

5. js壓縮圖片最低能壓縮多百分之多少

js最低能壓縮百分之一, 最大可放大至原來的5倍 2.👐最小可縮放至原來的百分之10 第二種保持圖片寬度長度不變改變圖片質量,但不能用於放大圖片 最小可壓縮至原圖的百分之一

6. 怎樣在客戶端 利用js 壓縮圖片 大小,然後上傳至伺服器比如2M壓縮成幾十KB

無法實現,js沒有許可權去修改本地文件的,只能是將大圖上傳到伺服器後再壓縮

7. web前端 圖片壓縮

我的理解應該是生成圖片的時候,在不影響圖片質量的情況下,盡量用體積小的格式,比如在不透明的情況下盡量把圖片保存成png格式。
在css中有一種技術叫做圖片精靈,就是把一些背景圖做成集合的形式。圖片只需載入一次。
最後網上好像是有插件(瀏覽器也有插件)可以對圖片進行壓縮處理。

8. js壓縮圖片 到固定像素以內,500k為例

本文旨在探究js壓縮圖片的兩種方式: 改變圖片長寬 改變圖片質量 ,和結合了以上兩者的 最終方案

首先,閱讀本文需要知道canvas的兩個方法

這兩個方法具體的說明可以在MDN上查看,關於圖片壓縮,也有很多現成的博客可以直接用。但是那些博客都有個問題,並沒有關心之後圖片的壓縮質量。
我試著用一個現成的例子去跑了一下,一個1.7M的圖片壓縮到了23k,堪稱像素級毀滅性破壞。

假如一張大圖可能包含著很多文字等關鍵信息,必須上傳之後使用方能清晰辨認。所以要壓縮之後質量盡可能接近500k的。500k像素以內,就是若一張圖寬度為1024,則高度不能超過500。因為圖片有其他的信息,也是要佔大小的。即不得大於 1024*500

所以,根據需求,上傳圖片不能超過500k的情況下盡可能保留圖片的清晰度。當然如果可以的情況下用上面提到的 canvas.toDataURL 設置壓縮程度為0.9,0.8試試看,圖片質量可以接受,大小會有大幅度的縮小。

如果不壓縮,靠調整圖片長寬去控制上傳大小呢?
原理很簡單,就是靠不斷地縮小限定的最大寬高,直到最終長寬的積小於規定的大小。
這種方法有可能最後得出的圖片的大小會略大於規定大小,原因上文也提到過了,如果想使用這種方法,可自行再調整一下。

上面的方法有個問題,就是改變了圖片的原始長寬。如果一個圖的長寬足夠大,壓縮圖片質量,糊一點但是內容看得清也是ok的嘛。所以,跟上面同理,我們可以不斷調整圖片的質量設定直到大小合適,那麼,如何在圖片上傳之前知道圖片的大小呢?
首先,需要知道的一點是,壓縮之後拿到的base64字元串會轉成blob對象,然後傳給服務端。
可以查閱文檔,blob對象有個屬性是size

這個size就是上傳之後實際的文件大小。
參照上面的思路,可以每次改變 canvas.toDataURL('image/' + fileType, level); level的值,去調整壓縮圖片質量,然後用blob對象的size去驗證是否滿足500k以內的需求。
關於 canvas.toDataURL 的level到底是怎麼計算的,MDN文檔里也沒說,寫了個循環一次減少0.1的level壓縮了幾個圖片

用加減乘除算了一下,沒找到規律,數學不好放棄了(這個東西好像也不是能觀察出來的,看結果跟初始大小沒啥關系)。
這里要注意的是,有可能遇到超大圖片,0.1的level可能不足以壓縮到500k,所以小於0.1的時候,改變level遞減的差值繼續壓縮下去

在開始接收到圖片的時候給一個loading增加用戶的耐心好了,loading萬歲~

其實單純的壓縮質量遇到稍大的圖片,會導致頁面高頻計算,然後頁面基本就用不了了- -。有嘗試過用iphone的一個屏幕截圖(10M左右),壓的時候稍過一會,整個手機都在發燙,只能殺進程。

所以,若對長度沒有特殊的限制,可以做一個縮放,去加快壓縮的進度,提高能壓縮的圖片大小上限。

頁面到了ios上還是不行- -,可以看到最後圖片level為0.001,最長邊為764。
問題還是循環次數還是過多,計算頻率太高。從圖中可看出,對於大圖來說,初始設定的level和圖片尺寸過於寬松,可以優化一下初始level和尺寸。

有的時候還會遇到一張圖片無論如何也壓不到500k,就是上一次和這次的壓縮後大小沒有變化,這種情況需要拋錯,不讓循環繼續。

大圖片的等待時間稍長,可以給用戶先預覽一個base64的圖片增加等待耐心,方法名為 getImgBase64 ,這里都一並給出了

解決的隱患:上面這個方案會出現我需要一個500k的照片,壓到了520k之後,再壓了一次。有時候這最後的一次會特別誇張,直接將圖片弄到了幾十k。
參考了: https://github.com/WangYuLue/image-conversion
這個庫裡面有個方法 compressAccurately ,這個方法可以比較精準地壓縮。偷偷翻了一下源碼。

其實上一個方案的痛點就在於,如何在每一個壓縮循環里處理尺寸和壓縮比例。

總結

如有紕漏,歡迎指正