我有一个存储在矢量中的像素数组,如下所示:
typedef union RGBA
{
std::uint32_t Colour;
struct
{
std::uint8_t R, G, B, A;
};
} *PRGB;
std::vector<RGBA> Pixels; //My pixels are read into this vector.
我使用以下两个函数处理它。一个是阅读,另一个是写作。 read函数接受一个字节数组并翻转它们并将它们存储到上面的结构中。它需要考虑填充,因此它适用于24位和32位位图。 write函数将其翻转并将其写入一个字节数组。
void ReadPixels(const std::uint8_t* In, RGBA* Out)
{
for (std::size_t I = 0; I < height; ++I)
{
for (std::size_t J = 0; J < width; ++J)
{
Out[(height - 1 - I) * width + J].B = *(In++);
Out[(height - 1 - I) * width + J].G = *(In++);
Out[(height - 1 - I) * width + J].R = *(In++);
Out[(height - 1 - I) * width + J].A = (BitsPerPixel > 24 ? * (In++) : 0xFF);
}
if(BitsPerPixel == 24)
In += (-width * 3) & 3;
}
}
void WritePixels(const RGBA* In, std::uint8_t* Out)
{
for (std::size_t I = 0; I < height; ++I)
{
for (std::size_t J = 0; J < width; ++J)
{
*(Out++) = In[(height - 1 - I) * width + J].B;
*(Out++) = In[(height - 1 - I) * width + J].G;
*(Out++) = In[(height - 1 - I) * width + J].R;
if (BitsPerPixel > 24)
*(Out++) = In[(height - 1 - I) * width + J].A;
}
if(BitsPerPixel == 24)
Out += (-width * 3) & 3;
}
}
问题是,如果我想改变数组中的一个像素,我必须翻转并将整个图像复制到矢量中,使用以下方法更改像素:
inline void SetPixel(int X, int Y, std::uint32_t Color)
{
Pixels[Y * width + X].Colour = Color;
}
然后将其翻转回阵列。有没有更好的方法来更改阵列中的单个像素而不必每次都这样做?
我尝试了这个公式(以便考虑填充):
ByteArray[((height - 1 - Y) * width + X) + (Y * ((-width * 3) & 3))] = Color;
但它不起作用。有什么想法吗?
答案 0 :(得分:2)
你的下标 - &gt;索引公式看起来都错了。
也许:
int stride = width * BitsPerPixel/8;
stride = ((stride - 1) & ~3) + 4; // round up to multiple of 4 bytes
RGBQUAD& selected_pixel = *reinterpret_cast<RGBQUAD*>(array + stride * (height - 1 - Y)) + X * BitsPerPixel/8);
selected_pixel.R = ...
...