I'm using C and stb_image, and image data is stored in an unsigned char*
where a group of 4 elements represents a pixel, with r, g, b, and a channels respectively. I'm trying to get pixels of part of an image, for a sort of spritesheet loader. Currently I have this:
static void getGlyphTexture(unsigned char *dataOut, unsigned char *dataIn, size_t bitmapWidth, size_t glyphSize, size_t index) {
for (size_t y = 0; y < glyphSize; y++) {
for (size_t x = 0; x < glyphSize; x++) {
dataOut[4 * (glyphSize * x + y) + 0] = dataIn[4 * (bitmapWidth * x + y) + 0];
dataOut[4 * (glyphSize * x + y) + 1] = dataIn[4 * (bitmapWidth * x + y) + 1];
dataOut[4 * (glyphSize * x + y) + 2] = dataIn[4 * (bitmapWidth * x + y) + 2];
dataOut[4 * (glyphSize * x + y) + 3] = dataIn[4 * (bitmapWidth * x + y) + 3];
}
}
}
The above code takes in an image dataIn
and outputs part of the image into dataOut
. It works fine right now, copying the very first segment of the image, of glyphSize * glyphSize
dimensions.
However, I cannot figure out the math to get the pixels offset from that starting point, say to get this part of the spritesheet.
I either get a buffer overflow error, or the data is not correct at all. Does anyone have any idea on the correct math to manipulate the array to select all the latter parts of the image?
Answers
To modify your code to extract a specific part of the image, you need to adjust the starting point from where you begin copying pixels. Here's how you can modify your getGlyphTexture
function to achieve this:
static void getGlyphTexture(unsigned char *dataOut, unsigned char *dataIn, size_t bitmapWidth, size_t glyphSize, size_t indexX, size_t indexY) {
for (size_t y = 0; y < glyphSize; y++) {
for (size_t x = 0; x < glyphSize; x++) {
size_t srcIndex = 4 * ((indexY * glyphSize + y) * bitmapWidth + (indexX * glyphSize + x));
size_t destIndex = 4 * (glyphSize * y + x);
dataOut[destIndex + 0] = dataIn[srcIndex + 0]; // Red channel
dataOut[destIndex + 1] = dataIn[srcIndex + 1]; // Green channel
dataOut[destIndex + 2] = dataIn[srcIndex + 2]; // Blue channel
dataOut[destIndex + 3] = dataIn[srcIndex + 3]; // Alpha channel
}
}
}
Here's how the changes work:
indexX
andindexY
represent the starting indices of the region you want to copy.- Inside the nested loops,
indexX * glyphSize
andindexY * glyphSize
determine the starting point in thedataIn
array from where you begin copying. - The variable
srcIndex
calculates the index in thedataIn
array corresponding to the current pixel being copied. destIndex
calculates the index in thedataOut
array where the pixel will be copied.
With these changes, you should be able to specify the starting indices of the region you want to extract from the image. For example, to extract the region shown in the second image you provided, you would call the function like this:
getGlyphTexture(dataOut, dataIn, bitmapWidth, glyphSize, 1, 2);
This would copy the region starting from the second column and the third row of glyphs. Adjust the values of indexX
and indexY
accordingly to extract different regions of the image.