最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript純前端實(shí)現(xiàn)在線(xiàn)GIF壓縮

 更新時(shí)間:2024年03月06日 08:42:09   作者:可樂(lè)雞翅kele  
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript純前端實(shí)現(xiàn)在線(xiàn)GIF壓縮工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前言

原因是我在寫(xiě)公眾號(hào)文章的時(shí)候,公眾號(hào)編輯器只能上傳最大10MGIF,而我剛好需要上傳的GIF超過(guò)了這個(gè)閾值。

所以我就隨便搜了一個(gè)壓縮GIF的工具,有一些壓縮完了下載需要付費(fèi),有一些不付費(fèi)就只能壓縮低于某個(gè)閾值的文件。

不過(guò)也能理解吧,畢竟別人也是需要賺錢(qián)的,這種文件的處理如果放在服務(wù)端做,那必然是要耗費(fèi)不少資源的,如果放在純前端做,又不能保證文件處理的速度。

然后我就想著GIF壓縮應(yīng)該不難吧,應(yīng)該有現(xiàn)成的工具庫(kù)吧,于是我就開(kāi)始動(dòng)手去實(shí)現(xiàn)一個(gè)GIF壓縮工具。這里我很執(zhí)拗地要去實(shí)現(xiàn)一個(gè)純客戶(hù)端的GIF壓縮(也不知道為啥我這么執(zhí)拗。)

初探GIF壓縮

我們都知道GIF是一張張靜態(tài)的圖片播放形成的動(dòng)圖,所以我一開(kāi)始就想著,如果我有一個(gè)庫(kù),能幫我把GIF所有幀都抽取出來(lái),然后我對(duì)所有幀的圖片進(jìn)行一個(gè)縮放的有損壓縮,壓縮完之后再把所有圖片合成一個(gè)新的GIF,那么我不就把GIF給壓縮了么。

然后我就找到了gif.jsomggif.js這兩個(gè)庫(kù):

  • omggif負(fù)責(zé)解析GIF,獲取GIF的每一幀圖像
  • 把獲取到的每一幀圖像進(jìn)行處理了之后,使用gif.js合成GIF

那么可以寫(xiě)出下面的代碼,以下的代碼就是一個(gè)分離GIF幀+合成GIF的代碼,還沒(méi)有加上壓縮每一幀的邏輯:

fetch("/test.gif")
  .then((response) => response.arrayBuffer())
  .then((buffer) => {
    // 用omggif解析GIF
    let reader = new omggif.GifReader(new Uint8Array(buffer));

    // 創(chuàng)建新的gif.js實(shí)例
    let gif = new GIF({
      workers: 2,
      quality: 5,
      width: reader.width,
      height: reader.height,
    });

    const width = reader.width;
    const height = reader.height;

    // 創(chuàng)建canvas元素
    const imgs = [];
    // 遍歷所有的frames,并添加到gif.js實(shí)例中
    for (let i = 0; i < reader.numFrames(); i++) {
      let frameInfo = reader.frameInfo(i);
      let canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = height;
      let ctx = canvas.getContext("2d", { willReadFrequently: true });
      let imageData = ctx.createImageData(width, height);
      reader.decodeAndBlitFrameRGBA(i, imageData.data);
      ctx.putImageData(imageData, 0, 0);
      gif.addFrame(ctx, { delay: frameInfo.delay });
      imgs.push(canvas.toDataURL());
    }

    //預(yù)覽分離出來(lái)的幀
    const div = document.createElement("div");
    imgs.forEach((url) => {
      const img = document.createElement("img");
      img.src = url;
      div.appendChild(img);
    });
    document.body.appendChild(div);

    // 生成GIF并下載
    gif.on("finished", function (blob) {
      console.log("finish");
      let url = URL.createObjectURL(blob);
      document.querySelector("#img").src = url;
      const a = document.createElement("a");
      a.download = true;
      a.href = url;
      a.click();
    });

    gif.render();
  });

但是我分離幀之后發(fā)現(xiàn),分離出來(lái)的幀相當(dāng)奇怪:

而且合并之后的GIF感覺(jué)完全被破壞掉了,我不清楚是不是我的這種思路本身就是不可行的,還是說(shuō)這兩個(gè)庫(kù)不能這么用。是不是我這樣做了之后導(dǎo)致描述GIF的信息丟了?(比如調(diào)色盤(pán)或者其他的一些全局信息,評(píng)論區(qū)有大神可以指導(dǎo)一下么)

這種方式不可行之后,我又嘗試了一下別的方式。這一次我不再寄希望于純js實(shí)現(xiàn)的庫(kù),而是往wasm方向去探索。

然后我嘗試使用Rust去解析GIF,并返回所有解析后的圖片給前端,前端再去做有損壓縮,但這一做法耗時(shí)太長(zhǎng),也不是成功的嘗試,所以代碼就不放出來(lái)了。

接著我就想到了ffmpeg,我知道它有壓縮GIF的功能,而且他也有成熟的wasm版本,可以便捷地在前端引入使用,但是它壓縮后近10M的體積依舊讓人望而生畏。

gifsicle

在繼續(xù)搜索GIF壓縮等關(guān)鍵詞時(shí),發(fā)現(xiàn)了gifsicle這個(gè)庫(kù)。它是一個(gè)用于處理GIF圖像的命令行工具和庫(kù),提供了很多功能包括創(chuàng)建、編輯、優(yōu)化和調(diào)整GIF

ffmpeg對(duì)比起來(lái),它是一個(gè)更專(zhuān)注于GIF處理的庫(kù),所以體積會(huì)比ffmpeg肯定小不少,所以我就想著能不能弄一個(gè)它的wasm版本移植到瀏覽器中使用。

后面還真讓我找到了它對(duì)應(yīng)的wasm版本,具體鏈接可以查看:gifsicle-wasm-browse,這個(gè)庫(kù)GZip壓縮之后只有150K左右,完全不用擔(dān)心體積問(wèn)題。

使用gifsicle的時(shí)候,常常使用如下的手段去減少GIF的體積:

-O參數(shù):

  • O1:該選項(xiàng)對(duì)應(yīng)于輕度優(yōu)化,它會(huì)執(zhí)行一些基本的優(yōu)化步驟,刪除無(wú)用的圖像數(shù)據(jù)和元數(shù)據(jù),以減小文件大小。這個(gè)級(jí)別的優(yōu)化通常執(zhí)行較快,但可能不會(huì)最大限度地減小文件大小。
  • O2:中度優(yōu)化比輕度優(yōu)化更深入,它可能會(huì)花費(fèi)更多的時(shí)間來(lái)尋找更多的優(yōu)化機(jī)會(huì)。這通常會(huì)導(dǎo)致更好的壓縮比和更小的文件大小。
  • O3:最大優(yōu)化級(jí)別會(huì)執(zhí)行最深入的優(yōu)化,可能需要更多的時(shí)間來(lái)完成,但通常會(huì)實(shí)現(xiàn)最大的文件大小減小。這個(gè)級(jí)別的優(yōu)化可能對(duì)CPU和內(nèi)存的需求更高。

--loosy

  • --lossy 會(huì)減少圖像中使用的顏色數(shù)量,從而減小顏色表的大小。這會(huì)導(dǎo)致顏色的近似和失真,因?yàn)樵嫉念伾畔?huì)被近似為顏色表中的顏色。
  • --lossy 程度下,一些微小的圖像細(xì)節(jié)可能會(huì)被去除,以進(jìn)一步減小文件大小。這可能導(dǎo)致圖像的一些細(xì)節(jié)在視覺(jué)上的損失

減少顏色數(shù):

  • GIF中每個(gè)像素可以使用圖像調(diào)色板中的一種顏色,而顏色數(shù)量表示這些不同顏色的總數(shù)。GIF使用的顏色調(diào)色板通常是8位色,允許最多256種不同的顏色。
  • 減少GIF的顏色數(shù)量可以降低圖像的文件大小,因?yàn)閳D像中使用的顏色越少,每個(gè)像素的顏色信息所需的位數(shù)就越少。然而,減少顏色數(shù)量也可能導(dǎo)致圖像的視覺(jué)質(zhì)量下降,尤其是對(duì)于包含大量顏色細(xì)節(jié)的圖像。

刪除注釋和元數(shù)據(jù)

裁剪和縮?。鹤钪庇^的壓縮手段,屬于有損壓縮

調(diào)整幀速率:相當(dāng)于減少組成這個(gè)GIF文件的圖片數(shù)量,也是有損壓縮

具體實(shí)現(xiàn)

首先安裝gifsicle-wasm-browser這個(gè)包,然后簡(jiǎn)單搭建一個(gè)表單如下:

gifsicle的具體文檔,可以點(diǎn)擊這里查看。

在前端中可以參照以下方式來(lái)使用gifsicle

  gifsicle
    .run({
      input: [
        {
          file: buffer,
          name: "input.gif",
        },
      ],
      command: [command],
    })
    .then(async (res) => {

    });

GIF的壓縮過(guò)程中,常常會(huì)把多種壓縮方式結(jié)合起來(lái)使用。如果單純的想壓縮GIF的體積而不考慮GIF的質(zhì)量,那就直接使用縮放進(jìn)行有損壓縮就好了;如果想保留GIF的質(zhì)量的同時(shí)壓縮GIF的體積,那還是需要多方參數(shù)的組合嘗試。

壓縮前的圖像:

以下是我一些嘗試壓縮的參數(shù)以及壓縮前后的對(duì)比:

壓縮參數(shù): -O2 --lossy=180 input.gif --colors 64 --scale 0.8 -o /out/out.gif

  • 壓縮后:體積:4.0MB,顏色數(shù)量:64,幀數(shù)不變,分辨率不變
  • 執(zhí)行時(shí)間:72s

壓縮參數(shù):-O2 --lossy=180 input.gif --colors 32 --scale 0.8 -o /out/out.gif

  • 壓縮后:體積:3MB,顏色數(shù)量:32,幀數(shù)不變,分辨率不變
  • 執(zhí)行時(shí)間:60s
  • 可見(jiàn)圖像顏色已經(jīng)嚴(yán)重變形

壓縮參數(shù):input.gif --colors 64 --scale 0.5 -o /out/out.gif

  • 壓縮后:體積:3MB,顏色數(shù)量:64,幀數(shù)不變,分辨率變?yōu)橹耙话?/li>
  • 執(zhí)行時(shí)間:19s
  • 圖像較為模糊,顏色也有少許變形

可以看到在大多數(shù)的壓縮參數(shù)下,都需要較長(zhǎng)的執(zhí)行時(shí)間,這是因?yàn)檫@個(gè)wasm包還沒(méi)有實(shí)現(xiàn)多核處理,還沒(méi)辦法利用多核CPU的優(yōu)勢(shì),所以處理起來(lái)時(shí)間會(huì)比較長(zhǎng)。

總結(jié)

如果這個(gè)包實(shí)現(xiàn)了多核處理,執(zhí)行時(shí)間能縮短一些的話(huà),那么我覺(jué)得會(huì)有更多的GIF處理會(huì)放在前端來(lái)做。

我一直覺(jué)得純前端處理是一件很酷的事情,對(duì)于開(kāi)發(fā)者來(lái)說(shuō),無(wú)需承擔(dān)昂貴的計(jì)算資源成本,如果不想承擔(dān)服務(wù)器成本,這個(gè)時(shí)候還有一種解決方法就是做成桌面應(yīng)用,把任務(wù)處理的二進(jìn)制文件打包下載到用戶(hù)本地。

但如果是純前端實(shí)現(xiàn)的話(huà),對(duì)于使用者來(lái)說(shuō),無(wú)需下載任何東西,點(diǎn)開(kāi)即用。

所以后面也理解了網(wǎng)上一些壓縮GIF需要收費(fèi)的工具,一個(gè)好的在線(xiàn)GIF壓縮產(chǎn)品它能同時(shí)保證執(zhí)行速度、壓縮體積、壓縮質(zhì)量,這還是相當(dāng)不容易的。

以上就是JavaScript純前端實(shí)現(xiàn)在線(xiàn)GIF壓縮的詳細(xì)內(nèi)容,更多關(guān)于JavaScript GIF壓縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • jQuery實(shí)現(xiàn)文字自動(dòng)橫移

    jQuery實(shí)現(xiàn)文字自動(dòng)橫移

    本文詳細(xì)介紹了通過(guò)jquery尺寸相關(guān)函數(shù)實(shí)現(xiàn)文字自動(dòng)橫移的方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • js插件Jcrop自定義截取圖片功能

    js插件Jcrop自定義截取圖片功能

    這篇文章主要為大家詳細(xì)介紹了js插件Jcrop自定義截取圖片功能 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • JS的運(yùn)行機(jī)制之事件循環(huán)機(jī)制示例詳解

    JS的運(yùn)行機(jī)制之事件循環(huán)機(jī)制示例詳解

    事件循環(huán)是JavaScript實(shí)現(xiàn)異步編程的核心,通過(guò)單線(xiàn)程執(zhí)行模型協(xié)調(diào)同步代碼、回調(diào)隊(duì)列、異步事件及微任務(wù)和宏任務(wù),這篇文章主要介紹了JS運(yùn)行機(jī)制之事件循環(huán)機(jī)制的相關(guān)資料,需要的朋友可以參考下
    2025-07-07
  • 微信小程序:報(bào)錯(cuò)(in promise) MiniProgramError

    微信小程序:報(bào)錯(cuò)(in promise) MiniProgramError

    這篇文章主要介紹了微信小程序:報(bào)錯(cuò)(in promise) MiniProgramError,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • tsc性能優(yōu)化Project References使用詳解

    tsc性能優(yōu)化Project References使用詳解

    這篇文章主要為大家介紹了tsc性能優(yōu)化Project References使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 微信小程序?qū)崿F(xiàn)點(diǎn)餐小程序左側(cè)滑動(dòng)菜單

    微信小程序?qū)崿F(xiàn)點(diǎn)餐小程序左側(cè)滑動(dòng)菜單

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)點(diǎn)餐小程序左側(cè)滑動(dòng)菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • JS實(shí)現(xiàn)靈巧的下拉導(dǎo)航效果代碼

    JS實(shí)現(xiàn)靈巧的下拉導(dǎo)航效果代碼

    這篇文章主要介紹了JS實(shí)現(xiàn)靈巧的下拉導(dǎo)航效果代碼,通過(guò)自定義js插件腳本dropdown.js實(shí)現(xiàn)簡(jiǎn)單的下拉導(dǎo)航效果的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • JavaScript動(dòng)態(tài)代理的各種用法詳解

    JavaScript動(dòng)態(tài)代理的各種用法詳解

    動(dòng)態(tài)代理是ES6引入的強(qiáng)大功能,通過(guò)Proxy對(duì)象實(shí)現(xiàn),允許你攔截和自定義對(duì)目標(biāo)對(duì)象的操作,下面我將全面介紹JavaScript動(dòng)態(tài)代理的各種用法,需要的朋友可以參考下
    2025-09-09
  • 基于Bootstrap實(shí)現(xiàn)tab標(biāo)簽切換效果

    基于Bootstrap實(shí)現(xiàn)tab標(biāo)簽切換效果

    這篇文章主要為大家詳細(xì)介紹了基于Bootstrap實(shí)現(xiàn)tab標(biāo)簽切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 檢查表單元素的值是否為空的實(shí)例代碼

    檢查表單元素的值是否為空的實(shí)例代碼

    這篇文章主要介紹了檢查表單元素的值是否為空的實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06

最新評(píng)論

南木林县| 察雅县| 六盘水市| 蛟河市| 孟津县| 无为县| 梁山县| 大石桥市| 宁乡县| 鄂托克前旗| 辛集市| 阿坝| 新邵县| 泽州县| 庆城县| 兰西县| 共和县| 来凤县| 扎兰屯市| 高邑县| 菏泽市| 慈溪市| 新津县| 河西区| 安仁县| 县级市| 宜兴市| 宁远县| 汕尾市| 东港市| 平阴县| 天水市| 绩溪县| 昭平县| 康马县| 城市| 疏附县| 咸阳市| 且末县| 易门县| 丁青县|