跳转至

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. 窗口背景
  2. 对话框背景
  3. 面板背景
  4. 按钮背景

  5. 控件皮肤

  6. 输入框边框
  7. 按钮皮肤
  8. 进度条背景

  9. 界面元素

  10. 卡片效果
  11. 分割线
  12. 装饰元素

代码示例

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;
    }
};
  1. 缓存策略
    // 九宫格缓存管理
    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;
}

最佳实践

  1. 边距设置:合理设置 marginlefttoprightbottom 属性,确保九宫格分割位置正确
  2. 资源设计:在设计九宫格图片时,确保四个角部图案完整,边缘部分适合拉伸
  3. 性能优化:使用 autoFit 属性优化图片适应性
  4. 视觉效果:通过 alphascale 属性调整透明度和缩放效果

相关皮肤