Jump to content
  • Advertisement
hoahong

2D How to convert RGB to ARGB

Recommended Posts

Posted (edited)

Hi guys,

I get the code from StackOverflow to convert RGB (camera image) to RGBA

public static unsafe void RGB2RGBA_FastConvert4(int pixelCount, byte[] rgbData, byte[] rgbaData)
        {
            if ((pixelCount & 3) != 0) throw new ArgumentException();
            fixed (byte* rgbP = &rgbData[0], rgbaP = &rgbaData[0])
            {
                FastConvert4Loop(pixelCount, rgbP, rgbaP);
            }
        }
static unsafe void FastConvert4Loop(long pixelCount, byte* rgbP, byte* rgbaP)
        {
            for (long i = 0, offsetRgb = 0; i < pixelCount; i += 4, offsetRgb += 12)
            {
                uint c1 = *(uint*)(rgbP + offsetRgb);
                uint c2 = *(uint*)(rgbP + offsetRgb + 3);
                uint c3 = *(uint*)(rgbP + offsetRgb + 6);
                uint c4 = *(uint*)(rgbP + offsetRgb + 9);
                ((uint*)rgbaP)[i] = c1 | 0xff000000;
                ((uint*)rgbaP)[i + 1] = c2 | 0xff000000;
                ((uint*)rgbaP)[i + 2] = c3 | 0xff000000;
                ((uint*)rgbaP)[i + 3] = c4 | 0xff000000;
            }
        }

And Convert RGB to RGBA like this:

byte[] rgb = new byte[800*600*3];
byte[] rgba = new byte[800*600*4];
RGB2RGBA_FastConvert4(800 * 600, rgb, rgba);

But i need to convert RGB TO ARGB too, so anybody can please help me?

Thanks

Edited by hoahong

Share this post


Link to post
Share on other sites
Advertisement

If I'm not mistaken, it should be a simple matter of adding a bit shift, and or'ing with a different value than the one you're using currently. I think if you consider how RGBA and ARGB are laid out in memory, respectively, the details should become apparent. (Again, assuming I'm not overlooking anything.)

Share this post


Link to post
Share on other sites
Posted (edited)
13 minutes ago, Zakwayda said:

If I'm not mistaken, it should be a simple matter of adding a bit shift, and or'ing with a different value than the one you're using currently. I think if you consider how RGBA and ARGB are laid out in memory, respectively, the details should become apparent. (Again, assuming I'm not overlooking anything.)

Can you tell me where to add the bit shift?

Edited by hoahong

Share this post


Link to post
Share on other sites
Posted (edited)

Why is your pixelCount 800*600 but in RGB2RGBA you check that it is divisible by 3 while in the loop... Well... I don't even know what you do, it is just completely wrong. You are reading 4 colors for each RGB pixel, but actually you're reading just red from 4 different pixels. You are reading 4 bytes (uint) from a byte pointer, which means at the end you will read past the allocated memory. Furthermore, you are assuming that the CPU uses little endian, which is true for most CPUs (especially x86) but you still shouldn't rely on that.

Edited by Magogan

Share this post


Link to post
Share on other sites
5 minutes ago, Magogan said:

Why is your pixelCount 800*600 but in RGB2RGBA you check that it is divisible by 3 while in the loop... I don't even know what you do, it is just completely wrong. You are reading 4 colors for each RGB pixel, but actually you're reading just red from 4 different pixels. You are reading 4 bytes (uint) from a byte pointer, which means at the end you will read past the allocated memory. Furthermore, you are assuming that the CPU uses little endian, which is true for most CPUs (especially x86) but you still shouldn't rely on that.

Thank you so much! @Magogan

Can you help me to solve my problem? That code i got from StackOverflow.

Share this post


Link to post
Share on other sites

For every pixel i from 0 to resolution-1 (for (i=0; i < pixelCount; ++i)) you just set pRGBA[i*4+k] = pRGB[i*3+k] for k=0,1,2 and then set pRGBA[i*4+3] = 255 (the alpha value).

Share this post


Link to post
Share on other sites
2 minutes ago, Magogan said:

For every pixel i from 0 to resolution-1 (for (i=0; i < pixelCount; ++i)) you just set pRGBA[i*4+k] = pRGB[i*3+k] for k=0,1,2 and then set pRGBA[i*4+3] = 255 (the alpha value).

Yes, Thank you so much. I will try and need your helps again.

Share this post


Link to post
Share on other sites

Your code sample

  • is completely #*@!ed up (some additions, some array access, absurd and unclear datatypes)
  • does not convert a RGB image to a RGBA image, it does some strange interleaving of bytes from a four channel source to a four channel destination

You should simply write into the corresponding channels of the destination pixels the red, green and blue values from the source image and the maximum alpha value (255 if channels are 8-bit unsigned integers, 65535 if they are 16 bit, 1.0 if they are floating point).

Label your data properly (r,g,b,a instead of c1-c4) to understand what you are doing and to figure out whether you are swapping channels accidentally.

Share this post


Link to post
Share on other sites
9 minutes ago, hoahong said:

Yes, Thank you so much. I will try and need your helps again.

I changed my code but it does not display anything

byte[] rgb = new byte[800*600*3];                       
byte[] rgba = new byte[800 * 600 * 4];
Marshal.Copy(pnVideoData, rgb, 0, rgb.Length);
                       
                        unsafe
                        {
                            fixed (byte* rgbP = &rgb[0], rgbaP = &rgba[0])
                            {
                                for (int i = 0; i < 800 * 600; i++)
                                {
                                    rgbaP[i * 4] = rgbP[i * 4];
                                    rgbaP[i * 4 + 1] = rgbP[i * 4 + 1];
                                    rgbaP[i * 4 + 2] = rgbP[i * 4 + 2];
                                    rgbaP[i * 4 + 3] = 255;
                                }
                            }
                        }

 

6 minutes ago, LorenzoGatti said:

Your code sample

  • is completely #*@!ed up (some additions, some array access, absurd and unclear datatypes)
  • does not convert a RGB image to a RGBA image, it does some strange interleaving of bytes from a four channel source to a four channel destination

You should simply write into the corresponding channels of the destination pixels the red, green and blue values from the source image and the maximum alpha value (255 if channels are 8-bit unsigned integers, 65535 if they are 16 bit, 1.0 if they are floating point).

Label your data properly (r,g,b,a instead of c1-c4) to understand what you are doing and to figure out whether you are swapping channels accidentally.

@LorenzoGatti 😭

Problem is that it is not my code, i get it on stackoverflow so i want to ask you guys here about that codes. I hope you can help my problem.

Thanks

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!