pixel conversion

Pages: 12
Mar 7, 2022 at 7:27pm
Mar 7, 2022 at 7:57pm
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 Mar 7, 2022 at 8:00pm
Mar 8, 2022 at 3:43am
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 Mar 8, 2022 at 3:45am
Mar 8, 2022 at 3:48am
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 Mar 8, 2022 at 3:49am
Mar 8, 2022 at 4:29am
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;
}

Mar 8, 2022 at 4:37am
You should not be treating any of this like anything but an array of bytes.
Mar 8, 2022 at 5:11am
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 Mar 8, 2022 at 9:31am
Mar 10, 2022 at 4:42am
Any comments?
Mar 10, 2022 at 6:03am
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.
Mar 10, 2022 at 6:23am
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 Mar 10, 2022 at 6:23am
Mar 10, 2022 at 7:07am
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 Mar 10, 2022 at 11:04am
Mar 10, 2022 at 11:28am
@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 Mar 10, 2022 at 6:19pm
Mar 10, 2022 at 12:07pm
Since the a value the 'least significant' byte it may look like this:

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

except I'm missing something?
Mar 10, 2022 at 6:13pm
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 Mar 10, 2022 at 6:31pm
Mar 10, 2022 at 6:25pm
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 Mar 10, 2022 at 6:28pm
Mar 10, 2022 at 6:29pm
How to convert RGBA 32bit to RGB24 bit image pixel here?
Mar 14, 2022 at 8:23am
Any comments or suggestions here?
Mar 14, 2022 at 10:53am
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
Mar 14, 2022 at 12:19pm
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 Mar 14, 2022 at 3:20pm
Mar 14, 2022 at 1:14pm
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 Mar 14, 2022 at 6:28pm
Pages: 12