GIF Splitter 會把動畫 GIF 中的每個可見幀,完整合成後輸出成 PNG,整個過程都在你的瀏覽器分頁內完成,因此你不必上傳原始檔案,就能把一段動畫中的一連串靜態畫面分享給別人。該頁面會在本機讀取 GIF,在正確的時間點套用前一幀的處置指令(disposal instruction),並將每個透明區塊繪製到完整的邏輯畫布上,再把那個完整畫布匯出成帶有編號的 PNG Blob。每個下載連結都指向一個由畫布像素實際建構出來的真實 PNG,而不是某個預存矩形,也不是由伺服器產生的檔案。幀編號會依照解碼後 GIF 的影像順序,從 1 開始;顯示的延遲時間是解碼後的顯示延遲(單位為毫秒);而 PNG 會保留完整的邏輯畫布尺寸,讓透明區域維持透明。當輸入被拒絕時,畫面會給出明確訊息,且不會留下任何部分提交的幀清單;而每一個暫存 URL 都會在輸出被替換、元件卸載,或你關閉分頁時被撤銷。這樣的組合,讓這個頁面在你想要把一段短動畫拆成一系列靜態畫面(用於文件、設計審查、社群貼文,或手動分鏡)時特別實用——也就是在實務上「贈送 Split Fiction 精彩片段」通常意味著的事情。

how to gift split fiction
how to gift split fiction

贈送一段 Split Fiction GIF 究竟代表什麼

如果你來到這裡是想分享一段動畫 GIF 片段(無論它捕捉的是 Split Fiction 的某個瞬間,還是其他任何動畫),其底層的工作就是把那個 GIF 拆成一張張完整合成的靜態畫面。這個頁面正好涵蓋了這樣的工作流程:一段小動畫載入到你的分頁中、一排編號過的預覽圖、以及一列即時產生的真實 PNG 下載檔案。實際的拆分動作,在 GIF Splitter 中只需要三個簡短的步驟,而本文接下來會逐一說明每個步驟會產生什麼,以及為什麼輸出會是那個樣子。

這個工作流程中的技術部分,正是這個工具值得使用的關鍵,勝過一般的轉檔工具。一段簡短的反應 GIF、合作對戰的精彩片段,或 UI 動畫,都可以很輕鬆地以單一檔案形式到處傳送;但若要把它拆成獨立的靜態畫面,用於留言串、部落格文章、簡報,或與朋友的聊天時,往往會讓你原本想保留的那個瞬間走味。有些工具只會回傳 GIF 內部儲存的原始變更矩形,結果產生裁切過、內容空缺的 PNG,無法真實呈現畫面上原本看到的幀。本文所介紹的這個頁面並不會這樣做。

為什麼 GIF 的原始區塊不等於實際可見的幀

動畫 GIF 格式比大多數現代的影像容器都來得老舊,並以一種特殊方式儲存幀。GIF 編碼器並不會為每一步都儲存一張完整的畫布,而是經常只儲存一個相對於前一幀有變化的小矩形。編碼器也可以把這個新矩形標記為透明、要求它在顯示後被清除,或要求在繪製下一幀之前先還原前一張畫布。有些區塊會在變更區域中包含透明像素,有些則不會。

若直接匯出這些原始矩形,將會產生誤導的縮圖與不完整的 PNG 檔案。一個閃爍的游標、一個會移動的貼圖,或一次部分的背景更新,都會變成一個被裁切的小方塊,而非使用者實際看到的完整幀。GIF Splitter 透過把每個儲存的區塊合成到目前的邏輯畫布上、在正確的時機套用前一幀的處置指令,並匯出最終完整的可見畫布,來避開這個問題。瀏覽器的畫布機制會被用於實際產生 PNG,這也是為什麼這個實作可以依賴標準的 Canvas API,而不必自己手寫光柵化程式。兩個相關的基礎方法已記錄於 MDN 的 putImageData 參考文件 以及 MDN 的 HTMLCanvasElement.toBlob 參考文件,這兩個畫布方法是本頁面最依賴的 API。

GIF 內部儲存的內容你在螢幕上實際看到的內容分割工具匯出的內容
一個在上一幀之後更新的小矩形一張保留所有先前內容的完整畫布合成後的完整可見畫布
一個被標記為透明的矩形會透出底下畫布的像素畫布保持透明的區域,輸出為透明的 PNG 像素
一個要求「還原為前一幀」的矩形與兩幀之前相同的畫布狀態還原後的完整畫布,匯出為一個 PNG
一個要求「顯示後清除」的矩形新內容原本所在的一塊空白區域完整 PNG 中同樣被渲染為空白的區域

在本機把 GIF 拆成 PNG 幀

實際的萃取步驟很短,而這個頁面會引導你完成整個流程。

  1. 選擇一個不超過 20 MB 的動畫 GIF。從你的裝置中挑選檔案;這個頁面會在本機讀取它,不會發送任何網路請求。檔案若超出 20 MB 上限、畫布尺寸超過支援範圍,或幀數超過 50 個影像幀,都會在任何 PNG 被建立之前就被拒絕。
  2. 選擇「Extract PNG frames」(萃取 PNG 幀),並等待本機合成步驟完成。這個頁面會解碼每個儲存的區塊、套用前一幀的處置指令,並在產生任何 PNG Blob 之前繪製出對應的畫布。在這個步驟中,所有資料都不會離開你的分頁。
  3. 檢視編號過的預覽圖,並下載你需要的完整 PNG 幀。每個預覽都會顯示其幀編號、畫布大小,以及解碼後的顯示延遲(單位為毫秒)。點選你想要那幀旁邊的下載連結,瀏覽器就會儲存一個依來源檔名加上補零幀編號來命名的編號 PNG,例如 animation-frame-01.png。

刻意使用補零編號,是為了讓檔案管理員與影像編輯器能依原本動畫的順序排列這些 PNG,因此在分享或上傳之前不必重新命名。下載你需要的幀,然後把輸出清單當作視覺上的稽核依據,再決定是否要刪除或替換原本的 GIF。

每張輸出 PNG 帶了哪些資訊

每個預覽都伴隨著三項參考資料,這些資料也會內建到任何你能在此之上建立的工作流程中:

  • 幀編號。幀編號會依照解碼後 GIF 的影像順序,從 1 開始。它不是對「最實用靜態畫面」的猜測,也不是智慧挑選的摘要,而是解碼後序列中的真實位置。
  • 畫布大小。PNG 會保留完整的邏輯畫布尺寸。這個工具不會把每幀裁切到變更矩形的大小,也不會調整影像大小,因此你在預覽中看到的畫面,將與你在檔案中取得的內容完全一致。
  • 解碼後的延遲。所顯示的延遲是解碼後的顯示延遲(單位為毫秒)。這是用來為這些靜態畫面排序的脈絡資訊,並不保證每個播放器或平台都會以完全相同的時機顯示原本的節奏。

由於 PNG 支援 alpha 通道,在已合成的 GIF 幀中的透明區域,只要瀏覽器畫布保留了透明度,就會維持透明。如果你需要更小的輸出影像,或一個全新的動畫 GIF,建議的做法是先檢查萃取出的幀,然後再使用 GIF Resizer 來調整尺寸,或使用 GIF Optimizer 來處理調色盤,而不是先動用那些工具。

決定分割能否完成的限制

這個頁面上的安全限制並非憑空設定;動畫檔案解壓縮後的大小,往往遠超過其原始位元組大小,一個看起來很小的上傳檔,也可能迫使分頁配置出不合理數量的畫布像素。已公告的邊界如下:

限制項目數值為何重要
來源檔案大小不超過 20 MB限制瀏覽器分頁內最初的讀取與解碼工作量。
畫布尺寸任一邊最多 4,096 像素確保單一幀能落在瀏覽器能穩定配置的畫布大小範圍內。
每幀像素數最多 3,000,000 像素避免大型畫布讓整體合成工作量倍增。
幀數最多 50 個影像幀限制這個頁面將產生的 PNG 下載總數。

在頁面開始產生 PNG 下載之前,會同時檢查總區塊工作量與合併後的輸出像素數。當輸入被拒絕時,畫面會給出明確訊息,且不會留下任何部分提交的幀清單,因此你絕對不會碰到一排半成品的預覽,還得在重試前手動清理。

在贈送或分享之前驗證幀的內容

在萃取完成後,請開啟第一張、中間一張,以及最後一張匯出的 PNG,並與原始動畫進行比對。請特別留意那些只變動畫布一部分的轉場,因為這正是「處置錯誤的區塊」會以突兀矩形方式顯示在 PNG 中的地方。如果該 GIF 使用了非常細微的透明度、色彩管理上的差異,或帶有損壞的擴充資料,則應在目標應用程式中檢視所產生的 PNG,而不是盲目信任。

對於任何你打算交出去的 GIF,有兩項檢查值得執行。首先,確認預覽圖在你真正想捕捉的那些瞬間與原始動畫一致,特別是圍繞著任何部分背景更新的位置。其次,確認這些 PNG 在檔案管理員或編輯器中開啟時,排序是否正確;補零的幀編號能讓排序保持可靠,但前提是這批檔案使用的來源檔名是一致的。

這個工具不會做的事

這個實作刻意保持範圍精簡,這也是它能持續穩定運作的原因之一。這個頁面無法還原瀏覽器解碼器讀不出來的幀、無法重建影片時間軸、無法保留 GIF 註解或應用程式擴充資訊、無法偵測重複的視覺幀,也無法推斷哪一張靜態畫面對你的特定任務最有用。它同樣不會上傳來源檔案,也不會保留萃取影像的永久副本。這個工具不會把多幀合併成接觸印樣(contact sheet)、不會加上檔名標籤、不會在透明區域後方繪製背景,也不會重新編碼為新的動畫。

如果你需要上述功能,最乾淨的做法是從萃取出的 PNG 開始,再把它們交給更專門的工具。Image Resizer 可以縮小這些靜態畫面;Photo Collage Maker 可以把它們排成接觸印樣;GIF Maker 則可以從挑選出的部分幀重建一個新的動畫。

延伸閱讀:為 PNG 加上背景說明:透明度是如何被取代的

延伸閱讀:無需上傳,為 GIF 加入文字用於 Discord 聊天