Bitwise Operations— How to change existing color?

后端 未结 2 1566
名媛妹妹
名媛妹妹 2020-12-18 14:05

I have read up on bitwise operators (& | ^) and I understand that if I were to do:

alpha = 0xFF000000 >> 24 ;
blue = 0xFF0000         


        
相关标签:
2条回答
  • 2020-12-18 14:45

    As EJP noted the masks are used to filter out the values for one of the color components/channels (Red, Green, Blue). And that's usually what you do with bit shift/masking operations. Everything else you do with the values you get is arithmetics or more advanced math.

    A color channel's range is 0-255, or 0x00 - 0xFF in hexadecimal values. To reconstruct it, you need to bitshift the components value back to their place. Which can be put together with simple arithmetic addition:

    // Example values
    int r = 255; // 0xFF
    int g = 1;   // 0x01
    int b = 15;  // 0x0F
    
    // go back to original form:
                          //    A  R  G  B
    int color = r << 16;  // 0x00.FF.00.00
    color += g << 8;      // 0x00.FF.01.00
    color += b;           // 0x00.FF.01.0F
    
    // just add back the alpha if it is going to be full on
    color = += 255 << 24; // 0xFF.FF.01.0F
    

    If you want to do some interpolation between colors you need to do it for each color component seperately, not all of them together in one integer. In some instances it may also a good idea to change the representation from [0-255] to a decimal one [0.0f-1.0f]:

    // Darken red value by 50%
    int color = ...; // some color input
    int mask = 0xFF;
    
    int a = (color >> 24) & mask;
    int r = (color >> 16) & mask;
    int g = (color >> 8) & mask;
    int b = color & mask;
    
    // convert to decimal form:
    float rDecimal = r / 255f; 
      // Let r: 0x66 = 102 => rDecimal: 0.4
    
    // darken with 50%, basically divide it by two
    rDecimal = r/2; 
      // rDecimal: 0.2
    
    // Go back to original representation and put it back to r
    r = (int)(rDecimal * 255); 
      // r: 51 = 0x33
    
    // Put it all back in place
    color = (a << 24) + (r << 16) + (g << 8) + b;
    

    Hope this helps out.

    0 讨论(0)
  • 2020-12-18 14:56

    I understand that if I were to do:

    No, you don't understand at all. The result of all your bitshifting is 0xff in all four cases, which is self-evidently incorrect. The alpha mask is 0xff000000, the blue mask is 0xff, the red mask is 0xff0000, the green mask is 0xff00. These are masks, which need to be applied to the actual pixel, with the & operator, to mask out the relevant channels. You need to understand that before you can go any further.

    0 讨论(0)
提交回复
热议问题