duilib库是可以支持在异形窗口下gif动画的,但是gif动画只有256色,目前项目中需要一个能够播放高清动画的游戏启动器,但真彩色的视频转成gif后失色严重,便想办法写了一个逐帧渲染png图片的类(其实是拿CGifAnimUI类改的),这个类支持webp格式,需要用的到google 的webp库,是所以用它是因为启动器的大小需求,120帧的png图片,一张1.2M左右,一起就是150M,经过webp的90%的有损压缩只有16M了,据我观察80%的有损压缩,肉眼也很难分辨出来。
#ifndef ImageAnimUI_h__
#define ImageAnimUI_h__
#pragma once
#include <vector>
namespace DuiLib
{
class CControl;
class UILIB_API CImageAnimUI :
public CControlUI
{
public:
struct AnimFrame
{
CDuiString m_pathImage; //图路径
Gdiplus::Image *m_pImage; //图
UINT m_spantime; //间隔
};
typedef std::vector<AnimFrame> AnimFrameList;
CImageAnimUI(void);
~CImageAnimUI(void);
LPCTSTR GetClass() const;
LPVOID GetInterface(LPCTSTR pstrName);
void DoInit() override;
void DoPaint(HDC hDC, const RECT& rcPaint) override;
void DoEvent(TEventUI& event) override;
void SetVisible(bool bVisible = true ) override;
void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue) override;
void SetBkImage(LPCTSTR pStrImage);
LPCTSTR GetBkImage();
void SetAutoPlay(bool bIsAuto = true );
bool IsAutoPlay() const;
void SetAutoSize(bool bIsAuto = true );
bool IsAutoSize() const;
void PlayGif();
void PauseGif();
void StopGif();
private:
void InitGifImage();
void DeleteGif();
void OnTimer( UINT_PTR idEvent );
void DrawFrame( HDC hDC ); // 绘制GIF每帧
void LoadAnimXmlFromFile(LPCTSTR pstrGifPath);
void initAnimXmlFromMemory( LPVOID pBuf,size_t dwSize );
Gdiplus::Image* LoadImageFromFile(LPCTSTR pstrGifPath);
private:
UINT m_nFramePosition; // 当前放到第几帧
CDuiString m_aniName; //动画名
CDuiString m_bkImage;
bool m_bIsWebp;
bool m_bIsAutoPlay; // 是否自动播放gif
bool m_bIsAutoSize; // 是否自动根据图片设置大小
bool m_bIsPlaying;
AnimFrameList m_framelist;
};
}
#endif // ImageAnimUI_h__
</