简体   繁体   中英

Set Pixel colour in an array

I have an array of pixels stored in a vector as follows:

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.

I process it using the following two functions. One is for reading, the other is for writing. The read function takes an array of bytes and flips them and stores them into the struct above. It takes padding into consideration so it works for both 24 and 32 bit bitmaps. The write function flips it back and writes it to an array of bytes.

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;
    }
}

The thing is, if I want to change just one pixel in the array, I have to flip and copy the whole image into the vector, change the pixel using:

inline void SetPixel(int X, int Y, std::uint32_t Color)
{
    Pixels[Y * width + X].Colour = Color;
}

And then flip it back into the array. Is there a better way to change a single pixel in the array without having to do this every single time?

I tried this formula (so that padding is taken into consideration):

ByteArray[((height - 1 - Y) * width + X) + (Y * ((-width * 3) & 3))] = Color;

But it doesn't work. Any ideas?

Your subscript->index formula looks all wrong.

Perhaps:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM