Chapter 141 · XUI 基础控件

Image 图像

Image 控件显示 Surface 纹理,支持多种 Fit 模式、对齐方式、源矩形裁剪与色调叠加。

141

概念

Image 控件用于在 UI 中显示图片:
• Fit 模式:Fill / Contain / Cover / None / Custom
• 对齐:9 宫格对齐(左上/居中/右下等)
• Source Rect:从大图中裁剪子区域
• Tint:颜色叠加(着色/变暗)
• CustomRect:自定义绘制区域

API 速查

函数说明
int xuiImageCreate(xui_context pCtx, xui_widget* ppW, const xui_image_desc_t* pDesc)创建图像控件
int xuiImageSetSurface(xui_widget pW, xui_surface pSurface)设置纹理
xui_surface xuiImageGetSurface(xui_widget pW)获取纹理
int xuiImageSetSource(xui_widget pW, xui_rect_t tSrc)源矩形
int xuiImageSetSourceRect(xui_widget pW, float fX1, float fY1, float fX2, float fY2)源矩形(分量)
int xuiImageClearSource(xui_widget pW)清除源裁剪
int xuiImageSetMode(xui_widget pW, int iMode)Fit 模式
int xuiImageSetAlign(xui_widget pW, int iAlignX, int iAlignY)对齐方式
int xuiImageSetTint(xui_widget pW, uint32_t iColor)色调叠加
int xuiImageSetColor(xui_widget pW, uint32_t iColor)整体颜色
xui_rect_t xuiImageGetDrawRect(xui_widget pW)实际绘制区域

编译本章示例

gcc -O2 -I. -o ch141.exe ch141_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch141.exe

示例:头像 + 图标

// 头像:Cover 模式填满圆形区域
xui_image_desc_t avatarDesc = { 0 };
avatarDesc.pSurface = pAvatarSurf;

xui_widget pAvatar;
xuiImageCreate(pCtx, &pAvatar, &avatarDesc);
xuiImageSetMode(pAvatar, 2); // Cover
xuiImageSetAlign(pAvatar, 1, 1); // 居中

// 图标:从图集中裁剪
xui_widget pIcon;
xuiImageCreate(pCtx, &pIcon, NULL);
xuiImageSetSurface(pIcon, pAtlasSurf);
xuiImageSetSourceRect(pIcon,
    32, 0, 48, 16); // 16x16 图标区域
xuiImageSetMode(pIcon, 0); // Fill 拉伸

// 着色图标
xuiImageSetTint(pIcon, 0xFFFF6B5E);

完整代码

将以下代码保存为 ch141_main.c,编译后运行即可看到图像控件效果:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;
static xui_surface g_pSurf;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = { 0 };
    d.iWidth = 800; d.iHeight = 600;
    d.sTitle = "ch141 - Image";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);

    xuiCreate(&g_pCtx);
    extern const xui_proxy_t tXgeProxy;
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 800, 600);

    /* 创建纯色纹理作为演示图像 */
    uint32_t pixels[64 * 64];
    for (int i = 0; i < 64*64; i++)
        pixels[i] = (i / 64 < 32) ? 0xFF6B5EFF : 0x5EFF8FFF;
    xui_surface_desc_t tSD = { 0 };
    tSD.iWidth = tSD.iHeight = 64; tSD.iFormat = XUI_SURFACE_FORMAT_RGBA8;
    tXgeProxy.surfaceCreate(&tXgeProxy, &g_pSurf, &tSD);

    /* 根容器 Column */
    xui_widget pRoot;
    xuiWidgetCreate(g_pCtx, &pRoot);
xuiWidgetSetLayoutType(pRoot, XUI_LAYOUT_COLUMN);
    xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 800, 600});
    xuiWidgetSetPadding(pRoot, 40, 40, 40, 40);
    /* 间距:用内联样式或子控件布局参数设置 */
    xuiSetRootWidget(g_pCtx, pRoot);

    /* 图像1:Fill 拉伸 */
    xui_image_desc_t img1 = { 0 };
    img1.pSurface = g_pSurf;
    xui_widget pImg1;
    xuiImageCreate(g_pCtx, &pImg1, &img1);
    xuiWidgetSetRect(pImg1, (xui_rect_t){0, 0, 128, 128});
    xuiImageSetMode(pImg1, 0); // Fill
    xuiWidgetAddChild(pRoot, pImg1);

    /* 图像2:Contain 保持比例 */
    xui_image_desc_t img2 = { 0 };
    img2.pSurface = g_pSurf;
    xui_widget pImg2;
    xuiImageCreate(g_pCtx, &pImg2, &img2);
    xuiWidgetSetRect(pImg2, (xui_rect_t){0, 0, 200, 100});
    xuiImageSetMode(pImg2, 1); // Contain
    xuiImageSetAlign(pImg2, 1, 1);
    xuiWidgetAddChild(pRoot, pImg2);

    /* 图像3:Tint 着色 */
    xui_image_desc_t img3 = { 0 };
    img3.pSurface = g_pSurf;
    xui_widget pImg3;
    xuiImageCreate(g_pCtx, &pImg3, &img3);
    xuiWidgetSetRect(pImg3, (xui_rect_t){0, 0, 96, 96});
    xuiImageSetTint(pImg3, 0xFFFF6B5E);
    xuiWidgetAddChild(pRoot, pImg3);

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • 纯色纹理:用 64×64 像素数组生成双色纹理,演示无需外部图片文件。
  • 代理 surfaceCreate:经渲染代理将像素数据上传为 GPU 纹理供 Image 控件使用。
  • Fill 模式:拉伸图像填满控件区域,不保持比例。
  • Contain 模式:保持比例缩放,图像完整显示在控件内。
  • Tint 着色:将颜色与纹理相乘,实现单色图标效果。

要点与陷阱

  • Mode:0=Fill 1=Contain 2=Cover 3=None 4=Custom。
  • Align:0=左/上 1=中 2=右/下。
  • Source:像素坐标,指定从纹理中取哪块区域。
  • GetDrawRect:布局后获取实际绘制矩形(调试用)。

进阶练习

  1. 图片浏览器:Contain 模式 + 切换不同图片。
  2. 精灵动画:定时切换 SourceRect 实现帧动画。
Image 图像效果
图:Image 图像渲染效果