2017-05-30 1 views
1

Je voudrais augmenter la luminosité d'une couleur. La couleur est enregistrée sous la forme d'un entier ARGB. L'opacité devrait rester la même. Est-il possible d'augmenter la luminosité en multipliant chaque couleur (RGB) par 2? Donc, quand ma couleur est: 0xFF010000 comment pourrais-je le décaler pour obtenir: 0xff020000?Java augmente la luminosité de couleur int avec le décalage de bits

+0

Alors voulez-vous changer seulement le dernier bit? –

+0

Non seulement le dernier bit, peut-être que j'ai donné un mauvais exemple. Quand la couleur R est 4 je veux que ça devienne 8, quand la couleur G est 2 je veux qu'elle devienne 4. Donc 0xFF040200 -> 0xFF080400 Ou est-ce que ce n'est pas comme ça qu'on augmente la luminosité d'une couleur? – Alexanus

Répondre

2

Les couleurs peuvent être éclaircis-with-désaturation avec une belle bithack:

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

Works en soustrayant chaque canal de 0xFF (avec ~pixel), en divisant par 2 (>> 1) nettoyer les bits qui décalé hors de leur canal (& 0x7F7F7F7F, a le bit supérieur de chaque octet réinitialisé) et puis soustrayant chaque canal de 0xFF à nouveau avec le premier ~. Comme il divise par deux la distance entre la valeur du canal et 0xFF, vous pouvez dire qu'il "ralentit" à mesure que la valeur augmente - donc ils ont tendance à s'égaliser, ce qui provoque la désaturation.

ressemble à ceci: enter image description here

Vous pouvez également utiliser l'échelle et désaturer, pour égayer sans désaturation, mais le revers est que tout canal qui est 0 sera coincé là-bas (noir ne peut pas être éclairci cette façon; jaune, cyan et magenta ne se déplace pas vers le blanc),

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

Cela fonctionne en calculant d'abord les canaux débordera, ce qui est quand leur bit haut (0x80808080) est réglé. Un masque faisant l'ensemble de ce canal 255 est calculé, appelé saturate. Ensuite, chaque canal est multiplié par deux sans débordement et la saturation est appliquée. Comme cela double la distance de la valeur du canal à zéro, il "accélère" à mesure que la valeur augmente, il n'y a pas beaucoup de désaturation (seulement lorsque les valeurs sont écrêtées en haut par saturation).

ressemble à ceci: enter image description here

Une variante mineure permet des canaux azurants qui sont zéro légèrement,

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

a la même que la précédente lorsque s'applique une fois, mais la différence devient clair en le faisant plusieurs fois.

J'ai modifié Alpha aussi parce que peu importe. Vous pouvez laisser cela en changeant les masques.

1

La valeur maximale pour chaque couleur est de 255, donc la multiplication d'une couleur par 2 (par transfert de bits ou autre) n'est probablement pas ce que vous voulez. Vous devriez probablement séparer chaque composant dans son propre int, appliquer la luminosité à tous ou plusieurs composants, puis recombiner.

Séparer chaque composant consiste simplement à appliquer un masque, puis à changer de bit si nécessaire.

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

application puis la luminosité, plutôt que doubler chaque composante de couleur, vous ne souhaitez réduire de moitié la distance Situés entre la couleur et le maximum (255), donc:

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

Une fois que vous avez accompli cela, il suffit de remonter la couleur (note, la valeur alpha readded de la valeur d'origine):

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

J'espère que ce que vous recherchez. Faites-moi savoir comment cela fonctionne pour vous.

+0

Je pense que vous avez utilisé RGBA au lieu de ARGB. Je vais changer un peu et essayer, merci – Alexanus

+0

@Alexanus Ah, vous avez dit ARGB, mes excuses. Il devrait être assez simple d'ajuster le code pour ARGB, je pense. Faites-moi savoir si vous rencontrez des problèmes. – Neil

1

Vous pouvez extraire les valeurs de couleurs correspondantes, puis les multiplier par 2, puis former de nouveau la couleur avec de nouvelles valeurs.

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;