# GIF 拆幀 — 每一幀存成一張 PNG

每一幀都單獨存成一張 PNG。

> 把動圖 GIF 拆成一幀一幀，每幀單獨存成 PNG，免費，全程在瀏覽器裡完成。透明和時長都保留下來。什麼都不上傳，斷網也能用。

本頁是一個完全在你的瀏覽器裡執行的互動式工具，地址是 https://abox.tools/zh-TW/split-gif/。你交給它的任何內容都不會被上傳。下面是這個頁面用文字對該工具的全部說明；要使用它，請開啟這個地址。

## 你的 GIF **不會上傳**。這裡根本沒有伺服器。

GIF 的讀取、解壓和繪製都由你自己的瀏覽器完成，每一張 PNG 也是在這臺機器的記憶體裡編碼出來的。就算這裡有什麼東西想把動圖送走，頁面的另一端也根本沒有伺服器可以接。

- ✗ 不上傳
- ✗ 不註冊
- ✓ 斷網可用
- ✓ 開源
- ✓ 檔案不出這臺機器

## GIF 拆幀的步驟

1. **選一個 GIF。** 拖到選擇框裡，或者自己找出來。瀏覽器直接從磁碟上讀，頁面會告訴你它看到了什麼：尺寸、幀數、播多久、循環幾遍。
2. **決定每張 PNG 裡放什麼。** **看上去的那一幀**是絕大多數人要的，也就是動畫在那一刻的整幅畫面。**只要這一幀真正存下的畫素**是檔案裡實際帶著的那塊補丁，保持它自己的大小和位置。GIF 之所以小就是靠它，而它並不是動畫看起來的樣子。
3. **決定透明怎麼處理。** PNG 能原樣保留透明，這是誠實的預設值。要是這些幀要拿去的地方根本不認透明、會把它變成黑色，那就改成填一個顏色。
4. **挑出你要的幀。** 預設全要。「每兩幀留一幀」用來給長錄影瘦身，網格裡的勾選框比它優先。編號從來不會變，所以不管你把鄰居丟掉多少，第 42 幀還是第 42 幀。
5. **下載。** 從網格裡一幀一幀存，或者打包成一個 ZIP 一次拿走，這樣儲存提示只彈一次，而不是幾百次。ZIP 裡可以放一個 `frames.txt`，寫明每一幀停留了多久，這是一堆 PNG 擺在資料夾裡唯一說不出來的事。

## 說得更細的版本

[怎麼把 GIF 拆成一幀一幀](https://abox.tools/zh-TW/guides/split-a-gif-into-frames/): 把動圖 GIF 的每一幀存成 PNG：為什麼有些幀只是畫面裡的一小塊、透明會怎麼樣，以及怎麼把時間留住，好把它再拼回去。

## 工具箱裡還有

- [GIF 分析](https://abox.tools/zh-TW/gif-analyzer/): 幀、延時、調色盤，以及每個位元組的去向。
- [圖片轉影片](https://abox.tools/zh-TW/images-to-video/): 一個資料夾的圖片，變成一段影片。
- [影片剪輯](https://abox.tools/zh-TW/trim-video/): 一邊看一邊標出要留的段落，最後拿回一個影片。
- [影片裁剪](https://abox.tools/zh-TW/crop-video/): 把片子切到只剩要緊的那塊。

## 常見問題

### 我的 GIF 會被傳到哪裡去嗎？

不會。檔案的讀取、解壓和繪製都由你自己的瀏覽器在你自己的硬體上完成，每張 PNG 也是在這裡的記憶體裡編碼的。這個工具沒有服務端，頁面的 `Content-Security-Policy` 裡寫著它允許聯絡的每一個地址，沒有一個屬於本站。拔掉網線，它照樣拆 GIF。

### 為什麼有一幀看起來像畫面的一小塊？

因為檔案裡存的就是那樣。GIF 是一張起始畫面加上後面一連串補丁：後面每一幀只存變化的那個矩形，螢幕上其餘部分是前面幾幀留在那裡的。一個人對著不動的牆說話，於是每幀存的是一張臉，而不是一整幅畫面，這個格式不至於大得離譜，全靠這一點。 \
\
你現在看到這個，是因為選的是「只要這一幀真正存下的畫素」。改成「看上去的那一幀」，每張 PNG 就都是動畫在那一刻的整幅畫面了。

### 透明保留得住嗎？

保留得住。GIF 的透明只有一位，一個畫素要麼畫上了要麼看不見，中間沒有過渡，而 PNG 存的正好就是這個，所以幀出來時透明區域是完好的。你要是更想要實心背景，把「透明區域」改成填一個顏色，那個顏色會寫進 PNG，之後就取不出來了。

### 為什麼幀延時不是我以為的數字？

GIF 裡每幀延時是按百分之一秒存的，而從九十年代起，瀏覽器就把小於兩個百分之一秒的值一律抬到十分之一秒。這條規矩是為當年那些轉動的地球圖寫的，後來一直沒刪。所以檔案裡寫 0.01 秒的幀，在哪裡都是按 0.10 秒播。這個工具顯示的是真正播出來的延時，兩者對不上時，會把檔案裡存的值寫在旁邊。

### 拆出來的幀還能拼回去嗎？

能，用本站的 [GIF 製作](https://abox.tools/zh-TW/gif-maker/)，或者任何接受一資料夾圖片的工具都行。ZIP 裡那個 `frames.txt` 就是為這個準備的：拆動圖會把時間資訊丟掉，因為 PNG 沒有地方記自己停留了多久，所以由這份清單把每幀的延時和位置一起帶出來。

### 幀可以存成哪些格式？

PNG，而且是有意只給 PNG。GIF 的一幀最多 256 色、一位透明，PNG 能原樣無損地存下來；換成 JPEG 就會把透明丟掉，憑空造出這一幀本來沒有的顏色，而且對平塗畫面來說通常還會更*大*。要是你確實需要 JPEG，事後用[圖片尺寸調整](https://abox.tools/zh-TW/resize-image/)轉一遍。

### 能讀的幀數有上限嗎？

沒有固定上限。真正的天花板是你機器的記憶體：GIF 在讀取過程中會膨脹到每幀每畫素約一個位元組，所以一個小檔案也可能是很大一塊記憶體。這個頁面寧可停下不讀，也不會讓分頁崩掉。真發生了它會說明，並把已經取到的幀交給你。

### 壞掉的 GIF 打得開嗎？

多數打得開。下載截斷、結束標記丟失、最後一幀在資料中間斷掉，這些都很常見，而一個見了就拒的讀取器，恰好對最需要拆開的那些檔案毫無用處。凡是完整的幀都會給出來，並附上哪裡不對。只有壓根不是 GIF 的檔案才會被直接擋掉。

### 它免費嗎，需要註冊嗎？

免費，沒有帳號，不用登入，也沒有試用期。幀上同樣沒有水印。本站帶廣告，經費就是從那裡來的，廣告拿不到任何關於你檔案的資訊。

### 斷網能用嗎？

能。頁面載入一次之後斷開網路，它照樣運作。這也是證明「什麼都沒上傳」最省事的辦法，真要把你的動圖送出去處理，拔線那一刻就停了。

## 這條隱私承諾怎麼核實

- **你的 GIF 沒有出去的路。** Content-Security-Policy 裡寫著這個頁面允許聯絡的每一個地址，沒有一個屬於本站。這裡沒有任何可以收走你檔案的接收端，就算有，程式碼裡也沒有把檔案送過去的東西。這行以前寫的是 `connect-src 'none'`，那是沒有例外的。加廣告付出的代價就是它，把這句說出來也是約定的一部分。
- **讀 GIF 的就是儲存庫裡的兩個檔案。** 瀏覽器會放 GIF，卻不會把它的零件交給你，所以格式是在這裡自己讀的：`src/gif.js` 是容器和 LZW 解壓，`src/compose.js` 是處置規則，決定前面幾幀墊在下面之後，這一幀看起來是什麼樣。開啟檔案不需要去取任何東西，第一次用也不會下載什麼引擎。
- **Google 載入了什麼，又拿不到什麼。** 廣告指令碼和統計指令碼來自 Google。關於你動圖的資訊，一條也沒有交給它們，檔案、某一幀、名字、尺寸、幀數都沒有。讀取、解壓、繪製、寫出圖片的每一行程式碼都由這個源提供，也都擺在儲存庫裡。
- **捐助按鈕載入了什麼，又拿不到什麼。** 頁首那個「Buy me a coffee」按鈕由 cdnjs.buymeacoffee.com 的指令碼畫出來，字型取自 Google Fonts。它不過是個連結，不上報訪問，也拿不到關於你或你檔案的任何東西。不點它就什麼都不會發生，點下去到的是別人的站。
- **斷網也照樣能用。** 斷開網路，這個頁面上每一部分都照常工作。這是最省事的一條證明，真要把你的動圖送出去拆，拔線那一刻就停了。

**你可以自己核對。**上面這些不用你信。這個頁面是儲存庫裡的模板和配置產生出來的，構建指令碼你能讀，也能自己跑一遍，跑出來的結果就提交在 `dist` 分支上。拿實際發給你的內容，跟你自己從原始碼構建出來的結果對一遍就知道了： https://github.com/A-Box-of-Tools/website

最值得先讀的幾個檔案：`config/site.toml` 裡是 Content-Security-Policy，`src/gif.js` 是負責解壓出每一幀的讀取器，`src/compose.js` 是把它們一層層疊起來的規則。兩者裡都沒有一行能碰到網路的程式碼。
