pixel conversion

Pages: 12
I think the problem is poorly phrased. (In fact, it seems to me to be deliberately confusing.) The endianness bit is nonsense — you should not be treating any of this like anything but an array of bytes.

All you are being asked to do is take a byte array of the form:

    r g b a r g b a r g b a

and eliminate every fourth byte:

    r g b r g b r g b

(I have used “r” for what the problem labels as “11”, and “g” for “22”, etc.)

[edited for more clarity]
Last edited on
I need to convert RGBA pixel to RGB pixel, there by eliminating Alpha value. Exactly what you mentioned here is correct. How can I convert thirty two bit PIXEL to twenty four bit PIXEL?
Last edited on
Forget the PIXEL. The problem is asking you to dink with byte arrays.

[edit] Part of the problem is to recognize that the way that the information is presented to you is confusing. Focusing on the PIXEL and 32/24 bit values is a distraction.
Last edited on
Something that I tried now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;

int main()
{
  cout << "RGBA color value is : ";
  unsigned int RGBA_1;
  unsigned int RGBA_2;
  unsigned int RGBA_3;
  unsigned int RGBA_4;
 
  cin >> RGBA_1 >> RGBA_2 >> RGBA_3 >> RGBA_4;

  unsigned int r = RGBA_1 << 24;
  unsigned int g = RGBA_2 << 16;
  unsigned int b = RGBA_3 << 8;
  unsigned int a = RGBA_4;

  unsigned int rgmask;
  unsigned int bgrmask;
  unsigned int rgbamask;

  rgmask = g | r;
  bgrmask = b | rgmask;
  rgbamask = a | bgrmask;

  cout << hex << rgbamask << endl;
  return 0;
}

You should not be treating any of this like anything but an array of bytes.
Do you mean to store RGBA image pixel data to character array like below?

unsigned char img[] = {
255, 0, 0, 0, // 1st RGBA pixel, completely red.
0, 255, 0, 0, // 2nd RGBA pixel, completely blue.
// and so on
};

Below is my function for pixel conversion.

1
2
3
4
5
6
7
8
9
10
11
12
13
void RGBAtoRGBPixelconvert(const uint8_t* rgba,
                      int pixelwidth,
                      uint8_t* rgb,
                      bool* opaque) {
  for (int i = 0; i < pixelwidth; i++) {
    const uint8_t* pixelin = &rgba[i * 4];
    uint8_t* pixelout = &rgb[i * 3];
    pixelout[0] = pixelin[0];
    pixelout[1] = pixelin[1];
    pixelout[2] = pixelin[2];
  }
}
Last edited on
Any comments?
Yes, where is your main() to test it?
1
2
3
4
int main ( ) {
    uint8_t rgba[16] = { ..... };
    uint8_t rgb[12] = { 0 };
    ....


You need to get past the stage of posting 'is this right' and develop your own skills to test your own code.
Where did that function signature come from?
What is 'opaque' for?
Doesn't the problem say the arrays should be int, not uint8_t?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <bitset>

union Pixel_with_alpha
{
    uint32_t word;
    uint8_t byte[4];
};

union Pixel_without_alpha
{
    uint32_t word;
    uint8_t byte[3];
};

void convert( Pixel_with_alpha &input, Pixel_without_alpha &output)
{
    for(int i = 0; i < 3; i++)
    {
        output.byte[i] = input.byte[i];
    }
}

int main()
{
    Pixel_with_alpha input[]{ {0x44332211}, {0x44331122} ,{0x44223311} };
    Pixel_without_alpha output{};
    
    for(int i = 0; i < 3; i++)
    {
        convert(input[i], output);
        std::cout << std::hex << input[i].word << " -> " << output.word << '\n';
    }
    std::cout << '\n';
    
    return 0;
}



44332211 -> 332211
44331122 -> 331122
44223311 -> 223311

Program ended with exit code: 0
Last edited on
@DizzyDon Here opaque means transparency(alpha). Typical alpha value is between 0.0(fully transparent) to 1.0(fully opaque). Ideally from RGBA pixel image, need to eliminate Alpha and finally RGB image is made. I was thinking about both image types to be uint8_t.
Last edited on
Since the a value the 'least significant' byte it may look like this:

rgb[...] = rgba[...] >> 8;

except I'm missing something?
Below is the code so far.
Should I replace uint8_t with short int or unsigned int, assuming RGBA values between 0-255 here?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>

using namespace std;

class RGB24bit
{
public:
	unsigned char R;
	unsigned char G;
	unsigned char B;

	RGB24bit(unsigned char r, unsigned char g, unsigned char b)
	{
		R = r;
		G = g;
		B = b;
	}

	bool Identical(RGB24bit rgb)
	{
		return (R == rgb.R) && (G == rgb.G) && (B == rgb.B);
	}
};


struct RGBA32BIT
{
    static constexpr RGBA32BIT red() { return RGBA32BIT(255, 0, 0); }
    static constexpr RGBA32BIT green() { return RGBA32BIT(0, 255, 0); }
    static constexpr RGBA32BIT blue() { return RGBA32BIT(0, 0, 255); }
    static constexpr RGBA32BIT black() { return RGBA32BIT(0, 0, 0); }
    static constexpr RGBA32BIT white() { return RGBA32BIT(255, 255, 255); }

    constexpr RGBA32BIT(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255)
        : r(r), g(g), b(b), a(a)
    {}

     uint8_t r;
     uint8_t g;
     uint8_t b;
     uint8_t a;
};

void process_with_rgba(const RGBA32BIT& rgba)
{
    cout<< "It is working for rgba" << "\n";
}

int main()
{
    process_with_rgba(RGBA32BIT::red());
    return 0;
}

OUTPUT
It is working for rgba

Last edited on
1
2
3
int constexpr stride = 4, span = 3;
for (int n = 0; n < n_pixels; ++n) 
  memcpy(dst + (n * span), src + (n * stride), span);

Use memmove if dst and src might alias.
Last edited on
How to convert RGBA 32bit to RGB24 bit image pixel here?
Any comments or suggestions here?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <bitset>

union Pixel_with_alpha
{
    uint32_t word_32;
    uint8_t byte[4];
};

union Pixel_without_alpha
{
    uint32_t word_24;
    uint8_t byte[3]; // ADJUST 3 TO SUIT HOW MANY 'CHANNELS' TO BE KEPT
};

void convert(Pixel_with_alpha &input, Pixel_without_alpha &output, size_t limit)
{
    for(int i = 0; i < limit; i++)
    {
        output.byte[i] = input.byte[i];
    }
}

int main()
{
    Pixel_with_alpha input[]{ {0xf4cc2211}, {0x44331100}, {0x4422ff11} };
    Pixel_without_alpha output{};
    
    size_t limit = sizeof(output.byte)/sizeof(std::byte);
    
    for(int i = 0; i < 3; i++)
    {
        convert(input[i], output, limit);
        std::cout
        << std::hex << input[i].word_32 << " -> " << output.word_24 << " -> ";
        
        for (int i = 2; i >= 0; i--)
        {
            std::cout
            << std::hex << std::bitset<8>(output.byte[i]).to_ulong() << '('
            << std::dec << std::bitset<8>(output.byte[i]).to_ulong() << ") ";
        }
        std::cout << '\n';
            
    }
    std::cout << '\n';
    
    return 0;
}


f4cc2211 -> cc2211 -> cc(204) 22(34) 11(17) 
44331100 -> 331100 -> 33(51) 11(17) 0(0) 
4422ff11 -> 22ff11 -> 22(34) ff(255) 11(17) 

Program ended with exit code: 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

int main()
{
const int syze{3};
uint32_t rgba[syze]{0xf4cc2211,0x44331100,0x4422ff11};	
uint8_t rgb[syze*3+1]; //cheating a little, 1 extra byte to make it simple

//the important part -------------------------
	for(int i{0},j{0}; i < syze*3; i+=3)
	{
		uint32_t *p {(uint32_t*)(&rgb[i])};
		*p = rgba[j++]; // >>8 if you want the first 3 bytes instead of last 3
		//if wrong endian, swap rgb[i] and rgb[i+2] here: 
//(if on a chip with endian reverse assembly command, use that on the int instead)
		std::swap(rgb[i],rgb[i+2]);
	}
//----------------------------------------	
	//uniportant print of output
	for(int i{0}; i < syze*3; i+=3)
		{
		  printf("%x %x %x\n", rgb[i], rgb[i+1], rgb[i+2]);
		}
}



cc 22 11
33 11 0
22 ff 11


if you need performance tuning, the swap has to be avoided. Its still probably best to let the cpu do that if it can.
Last edited on
Hi againtry

May I know how you arrive at these hard coded values? Are these assumptions here?
{0xf4cc2211}, {0x44331100}, {0x4422ff11} . I guess you assume little endian here, A:44,B:33,G:22,R:11 in memory and then read entire RGBA array and write it to RGB array, but after every 4bytes eliminate 255 for alpha? For RGBA image, the number is stored as a 32bit unsigned integer. So here the individual values will be like RRRRRRRR GGGGGGGG BBBBBBBB AAAAAAAA. Also there are 32 individual bits, 8 each of R, G, B, and A. But in my case here, ideally it must convert RGBA 32bit to RGB 24bit image.

Last edited on
Pages: 12