今天在網上找了些 PNG 格式的動態表情包我是不會告訴你是我是在 LINE 偷的表情包的,於是了解到是 APNG 這種格式。由於微信和 QQ 不支持 APNG,所以就把 APNG 轉為 GIF 了,在使用 APNG 轉換成 GIF 後,發現在微信上只能播放一次,就產生了如何批量修改 GIF 的循環次數的問題。
所以準備簡單介紹一下 APNG。並提供了一個在線工具,可以將 APNG 批量轉換為 GIF,但是該工具不能實現無限循環。所以分享了一個批量修改 GIF 循環次數的方法,使用了 Node.js 和批處理腳本兩種不同的實現方式。方便 Node 開發者和使用 Windows 的普通用戶直接批量處理。
APNG 是什麼?#
APNG(Animated Portable Network Graphics)是 PNG 的位圖動畫擴展,可以實現 PNG 格式的動態圖片效果。APNG 相比於 GIF 在圖片質量和細節表現方面更有優勢,而且隨著越來越多的瀏覽器對 APNG 的支持,它有望成為下一代動態圖的標準之一。主要有以下區別:
-
圖片質量:GIF 最多支持 256 種顏色,並且不支持 Alpha 透明通道,這導致 GIF 在色彩豐富的圖片和含有半透明效果的圖片上質量較差。而 APNG 可以支持更高質量的圖片,包括更多的顏色和 Alpha 透明通道,使得動畫效果更加細膩。
-
構成原理:APNG 和 GIF 都是由多幀構成的動畫,但是 APNG 的構成原理允許超自然向下兼容。APNG 的第一幀是標準的 PNG 圖片,即使瀏覽器不認識 APNG 後面的動畫數據,也可以無障礙顯示第一幀。而如果瀏覽器支持 APNG,就可以播放後面的幀,實現動畫效果。
-
瀏覽器支持:從 Chrome 59 開始,Chrome 瀏覽器開始支持 APNG,使得大部分瀏覽器都能顯示 APNG 動畫。唯獨 IE 瀏覽器不支持 APNG。
更多內容請參考:https://xtaolink.cn/268.html
APNG 批量轉 GIF#
該工具可以批量將 APNG 轉為 GIF,不過不能無限循環。
https://cdkm.com/cn/png-to-gif
批量修改 GIF 為無限循環#
bat(普通用戶請使用該方法)#
下面是使用批處理腳本(.bat)來實現相同的功能:
@echo off
setlocal enabledelayedexpansion
set "directoryPath=C:\path\to\directory"
for /r "%directoryPath%" %%f in (*.gif) do (
echo Modifying %%~nxf
call :modifyGif "%%f"
)
exit /b
:modifyGif
set "filePath=%~1"
set /p data=<"%filePath%"
set "index=!data:~0,16!"
set "modifiedData=!data:~0,16!!data:~16,1!!data:~17,1!!data:~19!"
echo.!modifiedData!>"%filePath%"
exit /b
請將C:\path\to\directory
替換為實際的目錄路徑。將上述代碼保存為.bat
文件,雙擊運行即可。腳本將遍歷指定目錄下的所有.gif
文件,並對其進行修改。
請注意,批處理腳本的功能相對有限,無法直接讀取二進制文件。上述腳本通過讀取文件的第一行來模擬讀取文件內容。在修改文件時,它直接將修改後的數據寫入文件,而不進行二進制操作。這種方法可能不適用於所有情況,尤其是處理大型文件時可能會有性能問題。如果需要更複雜的二進制文件處理,請考慮使用其他編程語言或工具來實現。
Node (Nexmoe 使用的該方法)#
const fs = require('fs');
const path = require('path');
function unlimitedGifRepetitions(path) {
const data = fs.readFileSync(path);
const index = data.indexOf(Buffer.from([0x21, 0xFF, 0x0B]));
if (index < 0) {
throw new Error(`Cannot find Gif Application Extension in ${path}`);
}
data[index + 16] = 255;
data[index + 17] = 255;
return data;
}
function batchModifyGifFilesInDirectory(directoryPath) {
fs.readdir(directoryPath, (err, files) => {
if (err) {
console.error('Error reading directory:', err);
return;
}
files.forEach(file => {
const filePath = path.join(directoryPath, file);
const fileExtension = path.extname(file);
if (fileExtension === '.gif') {
try {
const modifiedData = unlimitedGifRepetitions(filePath);
fs.writeFileSync(filePath, modifiedData);
console.log(`Modified ${file}`);
} catch (error) {
console.error(`Error modifying ${file}:`, error);
}
}
});
});
}
const directoryPath = './path/to/directory';
batchModifyGifFilesInDirectory(directoryPath);
請注意,上述代碼使用了 Node.js 的文件系統模塊(fs
)來讀取和寫入文件。此外,需要將./path/to/directory
替換為實際的目錄路徑。在執行該腳本之前,請確保已經安裝了 Node.js。
該腳本將批量遍歷指定目錄下的所有文件,並對後綴名為.gif
的文件調用unlimitedGifRepetitions
函數進行修改。修改後的數據將寫回原始文件。在控制台輸出中,你可以看到每個已修改的文件的信息或任何出現的錯誤信息。
更多內容參考:https://www.b612.me/golang/232.html
更好的工具#
這個批處理工具可以將多個 APNG 文件批量轉換為 GIF 文件,並且可以對轉換後的 GIF 文件批量設置為無限循環。