---
# System prepended metadata

title: 用 Hex Editor 修改 GIF 的播放次數
tags: [Blue 的學習紀錄]

---

---
tags: Blue 的學習紀錄
---

# 用 Hex Editor 修改 GIF 的播放次數

:::spoiler **播放 1 次的 GIF - 點擊展開圖片**
![gif - play one time](https://blueimgur.com/rhzheojn5i2.gif)
:::
:::spoiler **播放 5(or 6?) 次的 GIF - 點擊展開圖片**
![gif - play five times](https://blueimgur.com/RoOhepxqqqz.gif)
:::
:::spoiler **播放無限次的 GIF - 點擊展開圖片**
![gif - play infinite times](https://blueimgur.com/QQyhepxnbd4.gif)
:::

## 緣由

在使用 Win10 Mircosoft Store 上面一款用來錄製 GIF 的 APP 時，發現錄好的 GIF 只會跑一遍動畫，並不如想像中的應該是無限反覆播放

APP 上並沒有關於 GIF 播放次數的相關錄製設定。Google 搜尋「如何修改 GIF 播放次數」，得到的結果不外乎是需要 Photoshop，或是上傳到線上修改網站，但這類網站很可能會對我的圖片進行壓縮或降幀

又因為直覺猜想修改 GIF 播放次數應該會是個很簡單的事，也許就是找個文字編輯器對 GIF 內的某個數字做修改即可？所以就來研究怎麼修改 GIF 的播放次數

## 也許無法設定？

也許 GIF 的播放次數是由播放器來決定，並不是 GIF 檔案所設定的？

經過資料查詢後，GIF 的播放次數就是寫在 GIF 檔案裡面沒錯，所以修改 GIF 檔是正確的研究方向

## GIF 的檔案結構

主要是參考維基百科，上面寫得非常清楚：
<https://en.wikipedia.org/wiki/GIF>

關於播放次數的設定說明寫在這裡：
<https://en.wikipedia.org/wiki/GIF#Animated_GIF>

GIF 的播放次數設定會寫在一個叫做「Netscape Application Block (NAB)」的地方。==NAB 並不是標準 GIF 所必備的內容==，不含 NAB 的 GIF 的預設播放次數為 1 次，播放完便會停留在最後一個 frame

## Netscape Application Block (NAB)

關於 NAB 的詳細構造，可以參考這個連結：
<http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension>

![NAB at 0x30D](https://blueimgur.com/KLxheq0jqr4.png)

如上圖，擁有 NAB 的 GIF，其 NAB 會位於檔案內 `0x30D` 的位置，並且其位元會呈現如下：
21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 ==00 00== 00

==上面標註的兩個位元，就是決定 GIF 會播放幾次的位置==

注意，這兩組位元是以 ==Little-Endian== 的方式排序，也就是說，例如一組位元數 `00 01`，其所表示的數值是 `0x100`

關於 Big-Endian 和 Little-Endian，可以看這篇文章的圖解：
<https://blog.gtwang.org/programming/difference-between-big-endian-and-little-endian-implementation-in-c/>

## 編輯器的選擇

雖然 VS Code 上的 marketplace 有提供「Hex Editor」這款編輯器，但功能還不完全（2021/07），連刪除某組位元的功能也沒有，所以不適合用來編輯
<https://github.com/microsoft/vscode-hexeditor>

Google 搜尋後，我決定使用 HxD 這款編輯器，除了有台灣人支援的繁體中文翻譯，官方也有提供 portable 版本可供使用，不必安裝在電腦內
<https://mh-nexus.de/en/downloads.php>

## 進行編輯

在 HxD 打開欲要修改的 GIF 後，觀察其 `0x30D` 的位置：
![0x30D](https://blueimgur.com/VGmheq1rlj1.png)
可以發現，其位元並不是一個 NAB

NAB 必定呈現 `21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 ...` 的形式，與上圖不符，這表示這個 GIF 不含有 NAB，所以若想改變其播放次數，必須插入 NAB

複製以下 NAB 位元組：
:::info
21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 00 00 00
:::
> 結尾的 `00 00 00` 若改成 `05 00 00`，就是只播放 5 次

於 `0x30D` 的位置，進行==貼上插入==：
![貼上插入之前](https://blueimgur.com/f63heq2dgkj.png)
> 注意游標所插入的位置

完成後如下圖：
![貼上插入之後](https://blueimgur.com/skAheq2jiao.png)

儲存後開啟播放器，順利的話會發現修改成功！
![gif - play infinite times](https://blueimgur.com/QQyhepxnbd4.gif)

## 播放次數最終還是由播放器來決定

如果有留意到的話，文章最上方播放 5 次的 GIF，很可能其實播放了 6 次。但同樣一張 GIF，在我 win10 內建的圖片閱讀器，確實是 5 次沒錯

後來陸續在不同平台上進行觀察：

- Win10
  - 相片
    5 次
  - Line
    無限次
  - Chrome
    6 次
- IPhone 8
  - 相片
    6 次
  - Line
    6 次
  - Safari
    6 次
  - Chrome
    6 次

從以上觀察結果，可以得知雖然大部分都是 n+1 次，但並不是 GIF 內怎麼設定就一定會是如此，仍要取決於該媒體如何解讀 GIF 的內容
