SSkinImgFrame 九宫格图片皮肤¶
概述¶
SSkinImgFrame
是 SOUI 中专门用于处理九宫格图片的皮肤类型。它继承自 SSkinImgList
,通过将图片分割成九个部分,可以在保持边框效果的同时实现图片的自适应拉伸。
类定义¶
class SOUI_EXP SSkinImgFrame : public SSkinImgList
{
protected:
CRect m_rcMargin; // 九宫格边距
};
属性列表¶
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | string | - | 皮肤名 |
scale | float | - | 比例 |
alpha | int | - | alpha |
enableColorize | bool | - | enableColorize(是:1 |
autoFit | bool | - | autoFit(是:1 |
tile | bool | - | 平铺(拉伸:0 |
vertical | bool | - | 垂直排列(垂直:1 |
states | int | - | 子图数量(states) |
src | string | - | 数据源(src) |
filterLevel | string | - | filterLevel(none |
left | int | - | 左边距(left) |
top | int | - | 上边距(top) |
right | int | - | 右边距(right) |
bottom | int | - | 下边距(bottom) |
margin | string | - | 九宫格4周(margin) |
margin-x | int | - | 左右边距(margin-x) |
margin-y | int | - | 上下边距(margin-y) |
九宫格原理¶
九宫格将图片分为九个区域:
+------------+----------------+------------+
| 固定 | 拉伸 | 固定 |
+------------+----------------+------------+
| | | |
| 拉伸 | 拉伸 | 拉伸 |
| | | |
+------------+----------------+------------+
| 固定 | 拉伸 | 固定 |
+------------+----------------+------------+
XML示例¶
<!-- 基本用法 -->
<imgframe name="window_bg" src="img:window_bg" margin="5,5,5,5"/>
<!-- 分别指定四边距 -->
<imgframe name="button_skin"
src="img:btn_skin"
left="3" top="3" right="3" bottom="3"/>
<!-- 使用margin-x和margin-y -->
<imgframe name="dialog_bg"
src="img:dialog_bg"
margin-x="10" margin-y="5"/>
<!-- 带缩放和透明度 -->
<imgframe name="scaled_frame"
src="img:scaled_frame"
margin="8,8,8,8"
scale="1.2"
alpha="200"/>
使用场景¶
- 窗口背景
- 对话框背景
- 面板背景
-
按钮背景
-
控件皮肤
- 输入框边框
- 按钮皮肤
-
进度条背景
-
界面元素
- 卡片效果
- 分割线
- 装饰元素
代码示例¶
1. 创建皮肤¶
// 通过代码创建
SAutoRefPtr<SSkinImgFrame> pSkin;
BUILDSKINNATIVE(pSkin, SSkinImgFrame);
pSkin->SetImage(L"img:window_bg");
pSkin->SetMargin(CRect(5,5,5,5));
// 使用皮肤
SWindow *pWnd = new SWindow;
pWnd->SetSkin(pSkin);
2. 绘制实现¶
BOOL SSkinImgFrame::Draw(IRenderTarget *pRT, LPCRECT rcDraw,
DWORD dwState, BYTE byAlpha)
{
if(!m_pImg) return FALSE;
// 计算九宫格区域
CRect rcSrc = GetPartRect(dwState);
// 绘制九宫格
pRT->DrawBitmap9Patch(rcDraw, m_pImg, &rcSrc,
&m_rcMargin, m_bTile?EM_TILE:EM_STRETCH,
byAlpha);
return TRUE;
}
高级用法¶
1. 动态边距调整¶
class CAdaptiveFrame : public SSkinImgFrame
{
public:
void AdjustMargin(int nScale) {
m_rcMargin.left *= nScale;
m_rcMargin.top *= nScale;
m_rcMargin.right *= nScale;
m_rcMargin.bottom *= nScale;
}
};
2. 智能缩放¶
class CSmartScaleFrame : public SSkinImgFrame
{
protected:
virtual void OnScaleChanged(int nScale) {
// 根据缩放比例调整边距
CRect rcMargin = m_rcMargin;
rcMargin.Scale(nScale);
SetMargin(&rcMargin);
}
};
性能优化¶
1. 图片处理¶
// 图片预处理类
class CImagePreprocessor {
public:
static IBitmap* OptimizeForFrame(IBitmap* pOrigin,
const CRect& rcMargin) {
// 分析边框区域
// 优化图片大小和格式
return pOptimized;
}
};
- 缓存策略
// 九宫格缓存管理 class CFrameCache { public: static IBitmap* GetCachedFrame(LPCRECT rcDraw, SSkinImgFrame* pSkin) { SStringW strKey = GenerateKey(rcDraw, pSkin); if(!m_mapCache.Lookup(strKey)) { // 创建并缓存九宫格图片 IBitmap* pCached = BuildFrame(rcDraw, pSkin); m_mapCache[strKey] = pCached; } return m_mapCache[strKey]; } };
注意事项¶
1. 边距设置¶
- 合理设置边距值
- 考虑最小尺寸限制
- 处理边距过大情况
2. 图片要求¶
- 边框图案规则
- 纹理对齐准确
- 避免边框断裂
3. 性能考虑¶
- 控制原始图片大小
- 适当使用缓存机制
- 避免频繁重绘
常见问题解决¶
1. 边框变形¶
// 检查边距是否合理
BOOL IsValidMargin(const CRect& rcMargin, SIZE szImg) {
return rcMargin.left + rcMargin.right <= szImg.cx &&
rcMargin.top + rcMargin.bottom <= szImg.cy;
}
2. 拉伸失真¶
// 计算最佳缩放比例
float GetOptimalScale(SIZE szOrigin, SIZE szTarget,
const CRect& rcMargin) {
// 根据边距和目标大小计算最佳缩放比例
return fScale;
}
最佳实践¶
- 边距设置:合理设置 margin 或 left、top、right、bottom 属性,确保九宫格分割位置正确
- 资源设计:在设计九宫格图片时,确保四个角部图案完整,边缘部分适合拉伸
- 性能优化:使用 autoFit 属性优化图片适应性
- 视觉效果:通过 alpha 和 scale 属性调整透明度和缩放效果
相关皮肤¶
- 图片列表皮肤(SSkinImgList) - 基础图片列表皮肤
- 按钮皮肤(SSkinButton) - 支持渐变和圆角的按钮皮肤
- 渐变皮肤(SSkinGradation) - 支持线性渐变的皮肤