Java通过位移增加了int颜色的亮度

时间:2017-05-30 09:55:56

标签: java colors bit-manipulation

我想提高颜色的亮度。 颜色保存为整数ARGB。不透明度应该保持不变。 是否可以通过将每种颜色(RGB)乘以2来增加亮度? 因此,当我的颜色为:0xFF010000时,如何将其移位以获得:0xff020000

3 个答案:

答案 0 :(得分:2)

颜色可以通过良好的bithack变亮 - 去饱和度:

pixel = ~((~pixel >> 1) & 0x7F7F7F7F);

通过从0xFF(用~pixel)减去每个通道,除以2(>> 1)清除从其通道移出的位(& 0x7F7F7F7F,具有高位每个字节复位)然后再用第一个~从0xFF中减去每个通道。由于它将通道值和0xFF之间的距离减半,你可以说它在值上升时“减速” - 因此它们趋于均衡,从而导致去饱和。

看起来像这样: enter image description here

你也可以使用scale-and-saturate,在没有去饱和的情况下变亮,但另一方面是任何0的通道都会被卡在那里(黑色不能这样变亮;黄色,青色和洋红色不会移向白色),

uint saturate = ((p & 0x80808080) >> 7) * 255;
p = ((p & 0x7F7F7F7F) << 1) | saturate;

这首先计算哪些通道会溢出,即当它们的最高位(0x80808080)被设置时。计算整个通道255的掩码,称为saturate。然后将每个通道乘以2而不溢出,并应用饱和度。由于这会将通道值的距离加倍为零,因此随着值的增加,它会“加速”,没有太多的去饱和(只有当值被饱和时在顶部剪切时)。

看起来像这样: enter image description here

次要变体允许增亮零

的通道,

uint saturate = ((p & 0x80808080) >> 7) * 255;
p = ((p & 0x7F7F7F7F) << 1) | saturate | 0x01010101;

在应用一次时看起来与前一个相同,但多次执行时差异变得明显。

我也修改了Alpha,因为无论如何。你可以通过改变面具来解决这个问题。

答案 1 :(得分:1)

每种颜色的最大值为255,因此将颜色乘以2(通过位移或其他方式)可能不是您想要的。您可能应该将每个组件分成它自己的int,将亮度应用于所有或几个组件,然后重新组合。

分离每个组件只需要应用一个掩码,然后根据需要进行位移。

int red = (color & 0xff000000) >>> 24;
int green = (color & 0x00ff0000) >>> 16;
int blue = (color & 0x0000ff00) >>> 8;

然后应用亮度而不是每个颜色分量加倍,你只需要将颜色和最大值之间的距离减半(255),所以:

red = ((red - 255)/2 + 255);
green = ((green - 255)/2 + 255);
blue = ((blue - 255)/2 + 255);

完成此操作后,您只需重新组合颜色(注意,从原始值读取的alpha值):

color = (red << 24) + (green << 16) + (blue << 8) + (color & 0x000000ff);

我希望这就是你要找的东西。让我知道这对你有用。

答案 2 :(得分:1)

您可以提取相应的颜色值,然后将其乘以2,然后再次使用新值形成颜色。

int color = 0xff040200;

int blue = color & 0xff;           //last 8 bits value
color = color>>8;                  //We have stored last 8 bits so shift it.
int green = color & 0xff;          
color = color>>8;                  
int red = color & 0xff;            
color = color>>8;                
int alpha = color;                  //now color has only first 8 bits value.


//Make changes in the color;

blue = Math.max( blue<<1 , 255 ); 
green = Math.max( green<<1 , 255 ); 
red = Math.max( red<<1 , 255 ); 

//Now we need to form a new color
//reverse the steps of extraction of color from integer

int new_color = 0;

new_color = new_color | alpha;     //setting up the last 8 bits
new_color = new_color<<8;          //we have set last 8 bits so shift it.
new_color = new_color | red;     
new_color = new_color<<8;          
new_color = new_color | green;     
new_color = new_color<<8;          
new_color = new_color | blue;