I'm working on a simple bar graph application that uses a static array of colors for divvying out bar colors. I would like the functionality to either draw bars normally, or slightly transparent.
Is there a way to programmatically adjust a color integer so that it's slightly transparent? Or will I have to statically define a transparent version of each color and then switch to using these versions whenever I want transparency?
If you are using support library, you can use:
ColorUtils.setAlphaComponent(int color, int alpha);
If you are not using support library, one-line solution taken from it's source code is:
int res = (color & 0x00ffffff) | (alpha << 24);
Sure...Look at Color and there's a function:
static int argb(int alpha, int red, int green, int blue)
Return a color-int from alpha, red, green, blue components.
So your RGB values could be static and you just bump the alpha value to get a new transparent version of the color.
Hi there you could use the:
android.support.v4.graphics.ColorUtils#setAlphaComponent
note: the alpha here is from 0 to 255 and not % based.
There are also other util methods such contract and luminosity calculations in there.
Regards
Try following code
int color = (int)Long.parseLong(your_color, 16);
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
if color code has alpha then
int alpha= (color >> 24) & 0xFF;
From the top answer I created a method to do this:
private Android.Graphics.Color AddTransparencyToColour(Android.Graphics.Color color, int transparancy)
{
return Android.Graphics.Color.Argb(transparancy, color.R, color.G, color.B);
}
It's also worth noteing that this can be changed to an extension method like so
public static ColorExtensions
{
public static Android.Graphics.Color AddTransparency(this Android.Graphics.Color color, int transparancy)
{
return Android.Graphics.Color.Argb(transparancy, color.R, color.G, color.B);
}
}
In regards to the alpha value, from MSDN Color.FromArgb:
Remarks
To create an opaque color, set alpha to 255. To create a
semitransparent color, set alpha to any value from 1 through 254.
I use extension functions.
fun Int.withAlpha(#IntRange(from = 0, to = 255) alpha: Int): Int {
return (alpha shl 24) or (this and 0xFFFFFF)
}
Also possible with ColorUtils
ColorUtils.setAlphaComponent(color, alpha)
You could create a colour helper which returns same colour with applied alpha. - Lets say you want to change visibility from 0.0 to 1.0 (double)
val originalColour: Int = primaryColor
val generatedColor = ColorUtil.generateTransparentColor(originalColour, 0.5)
view.setBackgroundColor(generatedColor)
Create a colour generator helper
object ColorUtil {
fun generateTransparentColor(color: Int, alpha: Double?): Int {
val defaultAlpha = 255 // (0 - Invisible / 255 - Max visibility)
val colorAlpha = alpha?.times(defaultAlpha)?.roundToInt() ?: defaultAlpha
return ColorUtils.setAlphaComponent(color, colorAlpha)
}
}
Those in the compose world using androidx.compose.ui.graphics.Color can just use the copy-method:
val slightlyTransparentRed = Color.Red.copy(alpha = 0.9f)
Related
I have colors stored as IntArrays this is a simple function to convert to the argb color value used by Android.
fun IntArray.toColor(): UInt {
var color: Long = 0xFF000000
val maxIndex = size - 1
this.withIndex().forEach { (index, value) ->
color = color or (value.toLong() shl (8 * (maxIndex - index)))
}
return color.toUInt()
}
If you look at Android's own source code, you'll find color notation expressed as below
...
#ColorInt public static final int RED = 0xFFFF0000;
#ColorInt public static final int GREEN = 0xFF00FF00;
#ColorInt public static final int BLUE = 0xFF0000FF;
...
If I try to use the same value e.g. 0xFFFF0000 as Kotlin Int it's not possible, says the literal doesn't conform to the type Int. So I use UInt in my method.
Android's own code(in Java) android.graphics.Paint.setColor(#ColorInt int color) requires int and in my Kotlin Code I can only use and Int and not a UInt and when I use UInt.toInt() the value gets messed up.
Example
val color = arrayOf(0x11, 0x22, 0x33).toIntArray().toColor()
print(color.toString(16)) // ff112233 (UInt)
print(color.toInt().toString(16)) // -eeddcd (Int)
How do I convert any Kotlin type larger then Int to Int with the value intact?
Is it possible to solve this without calling Java in Kotlin?
Thanks
Kotlin Int should work well. Have you tried to use this value as color? Nevermind that color.toInt().toString(16) returns -eeddcd. It should return that because Int value dedicates highest bit for sign. That's representation issue, but the actual value is 0xff112233. So Kotlin Int with value -eeddcd when you pass it to setColor should look same as 0xff112233.
So try implement your function Int.toColor as follows:
fun IntArray.toColor(): Int {
var color: Int = 0xFF000000.toInt()
val maxIndex = size - 1
this.withIndex().forEach { (index, value) ->
color = color or (value shl (8 * (maxIndex - index)))
}
return color
}
I have tested the colors in working code. It's working fine, the issue is in Kotlin's string representation.
I am making a LibGdx application to be embedded as a Android Fragment.
I am having an issue with passing a Android colour resource to be used in LibGdx
This is my colour
<resources>
<color name="red">#FF0000</color>
</resources>
I pass this colour as follows
ContextCompat.getColor(getContext(),R.color.red)
This returns an int which I convert to float
I have a texture which is a white circle that I colour as so
spriteCircle.setColor(myColor)
This calls upon the Sprite class public void setColor (float color)
The output is not red but a different color
Using one of the Color constants from LibGdx com.badlogic.gdx.graphics.Color yields the correct result so my texture can be coloured correctly so I can rule that out.
My theory is that Android colour has a different format from LibGdx
I wrote this method to help convert that
private com.badlogic.gdx.graphics.Color convertColorToLibGdxColor(int color) {
float alpha = Color.alpha(color);
float red = Color.red(color);
float green = Color.green(color);
float blue = Color.blue(color);
return new com.badlogic.gdx.graphics.Color(red, green, blue, alpha);
}
Note that the Color.red method comes from the android.graphics.Color class
/**
* Return the red component of a color int. This is the same as saying
* (color >> 16) & 0xFF
*/
public static int red(int color) {
return (color >> 16) & 0xFF;
}
There is a method for blue, green and alpha is well.
Then I call the public void setColor (Color tint) from the Sprite class
What is interesting, If I use a Color constant from Android android.graphics.Color such as
#ColorInt public static final int RED = 0xFFFF0000;
It works fine but not my colour resource I posted above
When I compared the two, I can see that my colour resource has the alpha channel omitted so I decided the fill that portion in so now it is
<resources>
<color name="red">#FFFF0000</color>
</resources>
However, I still experience the same issue
Debugging the ContextCompat.getColor(getContext(),R.color.red)
yields a value 0xFFD4172A. I imagine the problem lies here
tl;dr Is it possible to translate a Android colour resource for use in LibGdx?
Thanks
There is actually a method for this in libgdx color class.
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/Color.html#argb8888ToColor-com.badlogic.gdx.graphics.Color-int-
It's also static method but instead of returning a new color, changing existing color.
Thanks to #deniz-yılmaz
LibGdx already has a method for parsing ARGB colours
private com.badlogic.gdx.graphics.Color convertArgbToLibGdxColor(#ColorInt int argbColor) {
com.badlogic.gdx.graphics.Color color = new com.badlogic.gdx.graphics.Color();
com.badlogic.gdx.graphics.Color.argb8888ToColor(color, argbColor);
return color;
}
I found a Gist which actually resolved my issue here
https://gist.github.com/steen919/8a079f4dadf88d4197bb/d732449eb74321207b4b189a3bcbf47a83c5db65
public final class ArgbHexToLibGdxColor {
private ArgbHexToLibGdxColor() {
}
/**
* Taken from https://gist.github.com/steen919/8a079f4dadf88d4197bb/d732449eb74321207b4b189a3bcbf47a83c5db65
* Converts the given hex color in 0xAARRGGBB format to a {#link Color} that can be used in a LibGdx application
*/
public static Color convert(long hex) {
float a = (hex & 0xFF000000L) >> 24;
float r = (hex & 0xFF0000L) >> 16;
float g = (hex & 0xFF00L) >> 8;
float b = (hex & 0xFFL);
return new Color(r / 255f, g / 255f, b / 255f, a / 255f);
}
/**
* Converts a Android color resource into a {#link Color} that can be used in a LibGdx application
*
* #see #convert(long)
*/
public static Color convert(#NonNull Context context, #ColorRes int colorRes) {
return convert(ContextCompat.getColor(context, colorRes));
}
}
This seems to work with colours obtained from the colors.xml file and the constants from the Android Color class
My Web API will send the background color for my views, Background color range is from white #ffffff to black #000000. So I can not set any fix text color for my information text.
What is the best way to set my text color?
I'm thinking to invert the background color and set it as my text color. But I don't know How can I invert Any color or Hex color code.
e.g if my web(background) color is #00ff11 then my text color will be #ff00ee.
For this, I search over stack but did not find any method for color conversion.
Thanks
Try this.
This will give rgb of your hex color. Now you can invert your colors as below.
int invertColor(String myColorString) {
int color = (int)Long.parseLong(myColorString, 16);
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color >> 0) & 0xFF;
int invertedRed = 255 - r;
int invertedGreen = 255 - g;
int invertedBlue = 255 - b;
int invertedColor = Color.rgb(invertedRed, invertedGreen, invertedBlue);
return invertedColor.toString();
}
private PaintType getNegativePaintType(String hexa) {
int color = Color.parseColor(hexa);
return new SolidColor((color & 0xFF000000) | (~color & 0x00FFFFFF));
}
getNegativePaintType("#00ff11") will return "#ff00ee"
Independently of the platform your using, you can achieve that using RGB values simply by subtracting the used color from it's base (255).
So for example:
color = (r,g,b)
invertedColor = (255-r,255-g,255-b)
Then you could transform it to hexadecimal value or whatever you need.
I am having a problem with an image processing app I am developing (newbie here). I am trying to extract the value of specific pixels by using the getPixel() method.
I am having a problem though. The number I get from this method is a huge negative number, something like -1298383. Is this normal? How can I fix it?
Thanks.
I'm not an expert, but to me it looks like you are getting the hexadecimal value. Perhaps you want something more understandable like the value of each RGB layer.
To unpack a pixel into its RGB values you should do something like:
private short[][] red;
private short[][] green;
private short[][] blue;
/**
* Map each intensity of an RGB colour into its respective colour channel
*/
private void unpackPixel(int pixel, int row, int col) {
red[row][col] = (short) ((pixel >> 16) & 0xFF);
green[row][col] = (short) ((pixel >> 8) & 0xFF);
blue[row][col] = (short) ((pixel >> 0) & 0xFF);
}
And after changes in each channel you can pack the pixel back.
/**
* Create an RGB colour pixel.
*/
private int packPixel(int red, int green, int blue) {
return (red << 16) | (green << 8) | blue;
}
Sorry if it is not what you are looking for.
You can get the pixel from the view like this:
ImageView imageView = ((ImageView)v);
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();
int pixel = bitmap.getPixel(x,y);
Now you can get each channel with:
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
getPixel() returns the Color at the specified location. Throws an exception if x or y are out of bounds (negative or >= to the width or height respectively).
The returned color is a non-premultiplied ARGB value.
Is there an easy way on Android to set the alpha component of a color retrieved from getResources().getColor(id)?
For example, this is what I'm currently doing to change an existing color to 70% opacity:
DrawerLayout drawerLayout = ...;
int color = getResources().getColor(R.color.bgColor);
color &= 0x00FFFFFF;
color |= (((int) (0.7 * 0xFF)) << 24);
drawerLayout.setScrimColor(color);
using the helper class Color. You can easily retrieve the four components, alpha, red, green, and blue, and set it back with Color.argb, for instance. The class has only static methods, and you don't need to instantiate it. E.g.
int alpha = Color.alpha(color);
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
int newColor = Color.argb((int)(alpha * 0.7f), red, green, blue);
Here you can find the documentation