基于C与stb_image提取精灵图指定区域像素的索引计算问题
修正精灵图Glyph提取的数组索引逻辑
原代码的核心问题有两个:未计算目标Glyph在精灵图中的起始偏移,以及行优先存储的坐标顺序搞反,同时缺少边界检查导致溢出风险。
关键逻辑梳理
图像数据采用行优先存储(先存完一行所有像素,再存下一行),RGBA每个像素占4字节。要提取第index个Glyph,需先确定它在精灵图中的起始位置:
- 计算精灵图每行能容纳的Glyph数量:
cols = bitmapWidth / glyphSize(假设精灵图是规则网格排列,每个Glyph尺寸为glyphSize×glyphSize) - 目标Glyph的起始X坐标(相对精灵图左上角):
startX = (index % cols) * glyphSize - 目标Glyph的起始Y坐标:
startY = (index / cols) * glyphSize
对于Glyph内部的每个像素(x, y)(x从0到glyphSize-1,y从0到glyphSize-1):
- 精灵图中对应像素的索引:
(startY + y) * bitmapWidth + (startX + x) - 输出缓冲区中对应像素的索引:
y * glyphSize + x
两者都需乘以4,对应RGBA四个通道的字节偏移。
修正后的代码
#include <assert.h> static void getGlyphTexture(unsigned char *dataOut, unsigned char *dataIn, size_t bitmapWidth, size_t glyphSize, size_t index) { // 边界检查,避免非法输入导致溢出 assert(glyphSize != 0); assert(bitmapWidth % glyphSize == 0); // 确保精灵图宽度是Glyph尺寸的整数倍 size_t cols = bitmapWidth / glyphSize; // 若已知精灵图高度,可补充bitmapHeight参数,增加index < cols * (bitmapHeight / glyphSize)的检查 assert(index < cols * cols); // 临时假设行列数一致,实际需根据精灵图尺寸调整 size_t startX = (index % cols) * glyphSize; size_t startY = (index / cols) * glyphSize; for (size_t y = 0; y < glyphSize; y++) { for (size_t x = 0; x < glyphSize; x++) { size_t inOffset = 4 * ((startY + y) * bitmapWidth + (startX + x)); size_t outOffset = 4 * (y * glyphSize + x); dataOut[outOffset + 0] = dataIn[inOffset + 0]; dataOut[outOffset + 1] = dataIn[inOffset + 1]; dataOut[outOffset + 2] = dataIn[inOffset + 2]; dataOut[outOffset + 3] = dataIn[inOffset + 3]; } } }
额外说明
- 若精灵图高度已知,建议补充
bitmapHeight参数,完善index的合法性检查,彻底避免越界访问。 assert用于调试阶段的边界校验,发布版本可替换为自定义错误处理逻辑。
内容的提问来源于stack exchange,提问作者Scollier
相关产品推荐
相关产品推荐

