2013-12-17 4 views
0

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

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; 

Но это не работает. Есть идеи?

ответ

2

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

Возможно:

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 = ... 
... 
Смежные вопросы