如何使用位操作将RGB转换为RGBA

时间:2015-12-04 22:29:21

标签: java colors bit-manipulation rgb bit-shift

我一直试图找出这个问题一天左右,而且我对正在发生的事情感到困惑。

基本上我有这个方法,以便将BGR整数转换为RGB并从中创建一个颜色

      Color c2 = new Color((BGRColorNumber & 0xFF),
    ((BGRColorNumber >> 8) & 0xFF),
    ((BGRColorNumber >> 16) & 0xFF));

可在此处找到颜色代码http://www.endprod.com/colors/

这很好用,但我现在尝试将其作为RGBA整数而不是RGB。我对Alpha如何适应RGB整数有点困惑。看起来如果你只有RGB或BGR或其他任何东西你只能做出alpha 1.0 / 255似乎,或者它还有更多呢?

以下是我一直在使用的代码

public class test 
{

public static void main (String[] args)

{

    test t = new test();


    System.out.println(t.asIntRGBA(4823790));

}

    public int asIntRGBA(int BGRColorNumber)
{



    int rgba = 
              (((int) (BGRColorNumber         & 0xFF) & 0xFF) << 16)
            | (((int) ((BGRColorNumber >> 8)  & 0xFF) & 0xFF) << 8 )
            | (((int) (BGRColorNumber >> 16)  & 0xFF) & 0xFF)
            | (((int) ((BGRColorNumber >> 24) & 0xFF) & 0xFF) << 24);

    Color c = new Color(rgba);

  Color c2 = new Color((BGRColorNumber & 0xFF),
    ((BGRColorNumber >> 8) & 0xFF),
    ((BGRColorNumber >> 16) & 0xFF));


  Color c3 = new Color(15637065);
  System.out.println((((int) ((BGRColorNumber >> 24) & 0xFF) & 0xFF) << 24) + " : " + c.getAlpha());
    System.out.println(String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()));
    System.out.println(String.format("#%02x%02x%02x%02x", c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()));
      System.out.println(String.format("#%02x%02x%02x%02x", c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()));
    return (rgba);
}

}

这是我的输出

0:255

&#34;#ee9a49ff&#34;

&#34;#ee9a49ff&#34;

&#34;#ee9a49ff&#34;

15637065

因此,如果我将其转换为颜色,然后输出RGBA,它会起作用,但我想为什么要浪费一个Object创建,然后在我可以执行colorInteger和Bitwise shift操作时获取值?

在Alpha通道上进行操作时,它给出了00/0,但是在使用Color.getAlpha()时;我给了ff / 255 ....?

我也不是100%肯定什么&lt;&lt; #是for,但似乎您放置了&gt;&gt;的值#into&lt;&lt; #。因此,如果我在红点上获得蓝色,并将其放入蓝点,那么红色也是如此。

在这种情况下,似乎Alpha处于24的最高位置,所以我假设这最初是ABGR ????

当我切换到

        int rgba = 
              (((int) (BGRColorNumber         & 0xFF) & 0xFF) << 24)
            | (((int) ((BGRColorNumber >> 8)  & 0xFF) & 0xFF) << 16)
            | (((int) ((BGRColorNumber >> 16)  & 0xFF) & 0xFF) << 8)
            | (((int)  (BGRColorNumber >> 24) & 0xFF) & 0xFF);

System.out.println(String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()));

我的输出是&#34;#9a4900ff&#34; 而不是&#34;#ee9a49ff&#34;

但是,如果我这样做

System.out.println(String.format("#%02x%02x%02x%02x",  ((rgba >> 24) & 0xFF),  ((rgba >> 16) & 0xFF),  ((rgba >> 8) & 0xFF), ((rgba >> 0) & 0xFF)));

我得到&#34;#ee9a4900&#34;这基本上是正常的,除了阿尔法的00 bug,除了它现在正在窃听trf .... ??????? 00而不是ee和Alpha现在是ff而不是00?

所以我很困惑我到底做错了什么......? 任何建议表示赞赏!

谢谢!

编辑:我意识到这可能是因为只有0到16的RGB位置,而且24本身并不存在,这就是为什么我对于任何我移位的东西都得到00的原因使用&#34;&lt;&lt;&lt;&lt;&lt;&gt;&#34;

进入24

也许我只需要将255 / ff放入24点的Alpha点并称之为一天。如果值为00,那么我只需要使它不是那样:)。

我仍然不明白为什么Color.getAlpha()返回ff,而不是00但是......?

编辑2:

所以我最终搞清了这个问题。

基本上我在第24位没有任何东西,只有0-23被用完了。这意味着我的最后8个24-31的值为0。

我也意识到颜色给了我ff / 255 for Alpha的原因,是因为我没有告诉Color我有一个Alpha值,所以它给它默认的ff / 255.

By doing Color c = new Color (#, true);

我能够打开Alpha值。

以下是我解决问题的方法。

public class test 

{

public static void main (String[] args)
{

    test t = new test();


    System.out.println(t.asIntRGBA(4823790));

}

    public int asIntRGBA(int BGRColorNumber)
{



    int rgba = 
              (((int) (BGRColorNumber         & 0xFF) & 0xFF) << 24)
            | (((int) ((BGRColorNumber >> 8)  & 0xFF) & 0xFF) << 16 )
            | (((int) ((BGRColorNumber >> 16)  & 0xFF) & 0xFF) << 8)
            | ((int) (252 & 0xFF) & 0xFF);

    Color c = new Color(rgba, true);
   // Color c3 = Color.TRANSLUCENT;

  Color c2 = new Color((BGRColorNumber & 0xFF),
    ((BGRColorNumber >> 8) & 0xFF),
    ((BGRColorNumber >> 16) & 0xFF), 252);


  Color c3 = new Color(-51471799, true);
  System.out.println(((rgba >> 24) & 0xFF) + " | " +  c.getRed() +  " | " + c.getGreen() + " | " + c.getBlue() + " | " + c.getAlpha());
  //System.out.println(();
    System.out.println(String.format("#%02x%02x%02x%02x",((rgba >> 24) & 0xFF), ((rgba >> 16) & 0xFF), ((rgba >> 8) & 0xFF), ((rgba) & 0xFF)));
    System.out.println(String.format("#%02x%02x%02x%02x", c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()));
      System.out.println(String.format("#%02x%02x%02x%02x", c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()));
    return (rgba);
}

}

我更改了使用&gt;&gt;获取值24只是给一个值(在这种情况下为252),进行测试。从技术上讲,他们都将是255。

这给了我正确的值,并根据上面的页面对应正确的十六进制值。

但是我遇到了

的问题
  System.out.println(String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()));

正确

正确输出:

&#34;#ee9a49fc&#34;

颜色输出:

&#34;#9a49fcee&#34;

如果我从rgba获得int值&#34; -291878404&#34;并将其插入Color c3,我获得与Color c相同的值。我不确定出了什么问题,但是我遇到了让所有问题都相同的问题。

RGBA

1 个答案:

答案 0 :(得分:0)

所以我遇到了一些麻烦,但我最终搞清了这个问题。

基本上我只能使用比特0-23,因为比特24-31没有给出任何数据。

首先,我必须将Alpha添加到24-31位,然后我必须将所有内容按比特移位到适当的RGBA顺序,来自ARGB。

如果我试图将所有内容转换为RGBA顺序,我会遇到问题,因为24中没有任何内容,并且出于某种原因,移位操作并不像正在发生的那样,所以我只进行两次整数操作。

公共课考试 {

public static void main(String [] args)     {

    test t = new test();


    t.asIntRGBA(4823790);

}

public int asIntRGBA(int BGRColorNumber)
{

    /*  
     *  First set of bit-wise shifts take the BGR value and swaps it into RGB values:
     *  Bits 24-31 - Alpha (Added in through this operation)
     *  Bits 16-23 - Red  (Originally Bits 0-7)
     *  Bits  8-15 - Green
     *  Bits   0-7 - Blue (Originally Bits 16-23)
     *  
     *  Seeing as we want Red as 24-31, and Alpha as 0-7, we need to do another bit-wise routine.
     *  We first have to add bit data to 24-31, before being able to shift it around.
     *  If you try to shift bits over in one routine it causes jumbling of bit data that isn't correct.
     *
     */

    /* 

    *  The Bit-Wise shift of (value >> #) is taking the value at Bit #.

    *  While the Bit-Wise sift of (x << #) takes the data of x, and puts it into Bit #.

    */

    int rgba = (((int) ((BGRColorNumber      )& 0xFF) & 0xFF) << 16)
            | (((int) ((BGRColorNumber >> 8 )& 0xFF) & 0xFF) << 8)
            | (((int) ((BGRColorNumber >> 16)& 0xFF) & 0xFF)    )
            | (((int) (25 & 0xFF) << 24));



   /*Once an Alpha value is stored in 24-31, you can now swap everything where they should be.

    * Since blue and red were swapped we now use (>> 16, not (>> 0/blank)).
    * As you can see we also swapped (<< 16 for << 24),
    * since now we are taking the value in Bits 16-23
    *                 and shifting them to Bits 24-31.

    * After this Bit-Wise shift we now have    

    *  Bits 24-31 - Red   (Originally Bits 16-23)
    *  Bits 16-23 - Green (Originally Bits 8-15)
    *  Bits  8-15 - Blue  (Originally Bits 0-7)
    *  Bits   0-7 - Alpha (Originally Bits 24-31)

    */
    int rgba2 = (((int) (rgba >> 16) & 0xFF) << 24)
            | (((int) (rgba >> 8 ) & 0xFF) << 16)
            | (((int) (rgba      ) & 0xFF) << 8)
            | (((int) (rgba >> 24) & 0xFF));



    Color c = new Color(rgba, true);

    Color c2 = new Color((BGRColorNumber & 0xFF),
                        ((BGRColorNumber >> 8) & 0xFF),
                        ((BGRColorNumber >> 16) & 0xFF), 252);


    Color c3 = new Color(435067465, true);
    System.out.println(rgba);
    System.out.println(((rgba2 >> 24) & 0xFF) + " | " +  c.getRed() +  " | " + c.getGreen() + " | " + c.getBlue() + " | " + c.getAlpha());
  //System.out.println(String.format("#%02x%02x%02x%02x%02x",((rgba >> 24) & 0xFF), c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()));


  //System.out.println(String.format("#%02x%02x%02x%02x",((rgba >> 24) & 0xFF), ((rgba >> 16) & 0xFF), ((rgba >> 8) & 0xFF), ((rgba) & 0xFF)));
   //System.out.println(String.format("#%02x%02x%02x%02x", c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()));
    System.out.println(String.format("#%02x%02x%02x%02x",((rgba >> 16) & 0xFF), ((rgba >> 8) & 0xFF), ((rgba >> 0) & 0xFF), ((rgba >> 24 ) & 0xFF)));
    System.out.println(String.format("#%02x%02x%02x%02x",((rgba2 >> 24) & 0xFF), ((rgba2 >> 16) & 0xFF), ((rgba2 >> 8) & 0xFF), ((rgba2 >> 0 ) & 0xFF)));
    System.out.println(String.format("#%02x%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()));
    System.out.println(String.format("#%02x%02x%02x%02x", c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()));

    return (rgba);
}

}