Установить цвет пикселей в массиве

У меня есть массив пикселей, хранящихся в векторе следующим образом:

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.

Я обрабатываю его, используя следующие две функции. Один для чтения, другой для письма.
Функция чтения берет массив байтов, переворачивает их и сохраняет их в структуре выше. Он учитывает отступы, поэтому работает как с 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

Решение

Ваш индекс-> индекс формулы выглядит все неправильно.

Может быть:

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 = ...
...
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]