圖像漸顯/漸隱是多媒體軟體常見效果,關鍵在於「速度控制」與「像素顏色快速變更」。傳統全圖掃描演算法過慢,難以呈現流暢動畫。本文解析利用 Windows 調色板動畫 與 時間碼定時 實現高效能漸變效果的核心技術,並提供關鍵程式碼架構。
Windows 提供 Palette Animation 技術:透過快速修改邏輯調色板中特定色表項的 RGB 值,即可在不移動像素資料的情況下,讓螢幕上對應像素瞬間變色。適用於 256 色 (8 位元) 圖像。
CPalette,呼叫 CreatePalette,將 LOGPALETTE 中每個 PALETTEENTRY 的 peFlags = PC_RESERVED,防止其他視窗搶佔色表。CDC::SelectPalette + CDC::RealizePalette 選擇並實現調色板。CPalette::AnimatePalette 修改色表項 RGB,產生漸變視覺效果。typedef struct tagPALETTEENTRY {
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags; // 必須為 PC_RESERVED
} PALETTEENTRY;
void CPalette::AnimatePalette(
UINT nStartIndex, // 起始色表索引
UINT nNumEntries, // 變更色表數量
LPPALETTEENTRY lpPaletteColors // 新色彩陣列指標
);
為將定時邏輯封裝於獨立函數,避免與視窗訊息迴圈糾纏,採用 PeekMessage 截獲 WM_TIMER 並即時處理:
// 設置定時器 (uTimeOut 為間隔毫秒)
pWnd->SetTimer(0x100, uTimeOut, NULL);
// 捕捉滑鼠,防止操作干擾
pWnd->SetCapture();
BOOL bDone = FALSE;
MSG msg;
while (!bDone) {
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_TIMER && msg.wParam == 0x100) {
// ===== 定時操作核心:呼叫 AnimatePalette 更新色表 =====
// 例如:線性插值計算下一幀 RGB,填入 PALETTEENTRY 陣列
// pPalette->AnimatePalette(startIdx, count, pEntries);
// 判斷動畫是否結束
if (/* 動畫完成條件 */) bDone = TRUE;
}
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
// 清理
::ReleaseCapture();
pWnd->KillTimer(0x100);
LOGPALETTE 並標記 PC_RESERVED。CPalette,選入目標 DC。WM_TIMER 到達,計算下一幀色表,呼叫 AnimatePalette。PC_RESERVED 並及時恢復。現代 Windows (Vista+) 建議使用 Layered Windows (WS_EX_LAYERED) + UpdateLayeredWindow 配合 Alpha 通道,或 Direct2D 繪圖管線實現硬體加速的淡入淡出,效能更優且無色深限制。