I wand to Theme a app in the same Color like my CM Theme and the App only allow to use a color picker,after looking in the shard preference of the app i found something. That's the Story but not the question.
This is what i found:
<int name="color_main_window" value="-13162859" />
My question is how i can generate this int from rgb/hex and the absolutely needed way from rgb/hex to int ?
An int is a 32-bit signed integer. So, -13161859 = 0xFF372695. A color will be represented as an ARGB int, so
a = FF
r = 37
g = 26
b = 95
The Color class has utility methods that can convert int to rgb or argb and vice versa.
Related
I am using the Android Philips Hue SDK and I am currently having an issue with converting the light bulbs XY value to RGB.
I have looked at this code provided in a forum on Philips Hue website and the code has been provided by someone from Hue Support.
I have the following function using this code from the forum:
public static int[] convertXYToRGB(float[] xy, String lightModel)
{
int color = PHUtilities.colorFromXY(xy, lightModel);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
return new int[] {r, g, b};
}
And I am calling it like:
int hue = lightState.getHue();
float[] xy = PHUtilities.calculateXY(hue, item.light.getModelNumber());
int[] rgb = Utilities.convertXYToRGB(xy, item.light.getModelNumber());
Looking at the RGB value I get back it seems to be the wrong colour. For example, using the official app, I set one of my light bulbs to red. When I run my app, the RGB value that comes back is a pale yellow.
Has anyone else experienced this or know how to resolve this issue?
I had a similar issue while programming a desktop application using the same Java SDK (login required). Interestingly, a plain red turned into a fade yellow, exactly how you describe it. A possible solution is to use the xy-values directly instead of the conversion from hue-values. That finally solved the problem for me. You can get the xy-values from the PHLightState object using the methods .getX() and .getY(). After that, use colorFromXY as in your code to get the RGB-values (as android color value = int).
PHLightState s = light.getLastKnownLightState();
float xy[] = new float[] {s.getX(), s.getY()};
int combRGB = PHUtilities.colorFromXY(xy, light.getModelNumber());
On Android, convert combRGB as you already do. Make sure to include android.graphics.Color. If you are testing on non-Android systems you can use the following code:
Color theColor = new Color(combRGB);
int[] sepRGB = {theColor.getRed(), theColor.getGreen(), theColor.getBlue()};
Note: The lights can only address a certain color gamut depending on the type. This is explained into detail here. The 'normal' bulbs with a color gamut B have quite some limitations. For example: most greens turn into yellows and the blues contain a certain amount of red.
Example values: The following overall conversions are tested on my live system with LCT001-blubs. I used PHUtilities.calculateXYFromRGB() to convert the input, then I set the xy-values of the new light state with .setX() and .setY() and finally sent it to the bridge. The values are then extracted from the light cache in the application as soon as it gets the next update.
255 0 0 -> 254 0 0
0 255 0 -> 237 254 0
0 0 255 -> 90 0 254
200 0 200 -> 254 0 210
255 153 0 -> 254 106 0
255 153 153 -> 254 99 125
I would also like to read out the colour of the pixels from an 'Image'. I've read a lot of topics here about this but the success is still missing.
So after a lot of unwanted values, I tried to simplify my code and the Image as well. I tried with the following:
//..
Android.Graphics.BitmapFactory.Options op = new BitmapFactory.Options();
op.InPreferredConfig = Bitmap.Config.Argb8888;
Bitmap b = Android.Graphics.BitmapFactory.DecodeResource(this.Resources, Resource.Drawable.Image, op);
//imageView.SetImageBitmap(b);
int pixel1 = b.GetPixel(3, 4);
int pixel2 = b.GetPixel(12, 11);
int pixel3 = b.GetPixel(19, 20);
int pixel4 = b.GetPixel(27, 28);
int pixel5 = b.GetPixel(27, 19);
int pixel6 = b.GetPixel(20, 11);
int redV1 = Android.Graphics.Color.GetRedComponent(pixel1);
int greenV1 = Android.Graphics.Color.GetGreenComponent(pixel1);
int blueV1 = Android.Graphics.Color.GetBlueComponent(pixel1);
int redV2 = Android.Graphics.Color.GetRedComponent(pixel2);
int greenV2 = Android.Graphics.Color.GetGreenComponent(pixel2);
int blueV2 = Android.Graphics.Color.GetBlueComponent(pixel2);
//..
Surprisingly I got the results as follows:
pixel1 color is OK.
pixel2 color is NOT OK its pixel1 color.
pixel3 color is NOT OK its pixel2 color.
pixel4 color is NOT OK its pixel2 color.
pixel5 color is NOT OK its pixel2 color.
pixel6 color is NOT OK its existing color in my Image but on different coordinates. (it was not mentioned in my code)
Presentation of the .png Image in an imageView seems to be smooth.
Could anyone help with my fault?
THX!
pixel1..6 values seems to be correct (different on different colours and equal on the same) and they would be enough for me but all the values became -1 after I start to work with my real .png file (1500x1500 image as a resource). Is that too large to work with? What is the maximum in this case? Thx!
... Ok, perhaps I got the fault. To be precise, not the fault but a usable solution! Now I'm trying with a smaller .png Image sized 500x500. It is small enough to work with.
BUT: It seems the BitmapFactory creates a larger image (1000 x 1000). So I have to divide each coordinate with 2 if I want to check the correct colour on my original image. AND there is another problem: Some colours may be different read by the Getpixel(). It can be small differences in R,G,B values. In example: RGB(148,0,198) instead of (153,0,204). It means a 'bit' extra work for me to identify all the new 'Android colours' on my bitmap :( I hope, I could help for the others with this topic. It wasn't easy to find one bug/problem after another.
I am trying to retrieve value of red, green,blue from pixel color value .So I need to perform some shift and multiply operation.But android studio notifying above error at following code.
clr=bm.getPixel(0,0);
cred=(clr & 0*ff)>>16;
tv.append((String.valueOf(clr)));
tv.append((String.valueOf(cred)));
ERROR:Cannot resolve Symbol ff at line no 2;
It should be 0xff and not 0*ff
cred=(clr & 0xff)>>16;
0*ff is multiplying 0 with unknown symbol ff (since you don't have any variable named ff in scope)
While above code will compile and resolve your error, it is not correct code for reading red color value from bitmap pixel. Correct code would be
cred = (clr >> 16) & 0xff;
But probably the easiest and safest way would be to use Color class.
int a = Color.alpha(clr);
int r = Color.red(clr);
int g = Color.green(clr);
int b = Color.blue(clr);
I am writing an Android application that must paint determined parts of a loaded bitmap image according to received events.
I need to paint (or change the current color) of a single part of a bitmap image, without changing the rest of the image.
Let's say I have a car, which is divided by many parts: door, windows, wheels, etc.
Each time an event (received from the network) arrives, I need to change the color of that particular part with the color specified by the event data.
What would be the best technique to achieve that?
I first thought on FloodFill, as suggested on many threads in SO, but given that the messages are received quite fast (several per second) I fear it would drag performance down, as it seem to be very CPU intensive algorithm.
I also thought about having multiple segments of the same image, each colored with a different color and show the right one at the right time, but the car has at least 10 different parts and each one could be painted with 4-6 colors, so I would end up with dozens of images and that would be impractical to handle, not to mention the waste of memory.
So, is there any other approach?
The fastest way to do it is with a shader. You'll need to use OpenGL ES 2 for that (some Androids only support ES 1). You'll need a temporary bitmap the same size as the image you want to change. Set it as the target. In the shader, retrieve a pixel from the sampler which is bound to the image you want to change. If it's within a small tolerance of the colour you want to change, set gl_FragColor to the new colour, otherwise just set gl_FragColor to the colour you retrieved from the sampler. You'll need to pass the desired colour and the new colour into the shader as vec4s with al_set_shader_float_vector. The fastest way to do this is to keep 2 bitmaps and swap between them as the "main one" that you're using each time a colour changes.
If you can't use a shader, then you'll have to lock the bitmap and replace the colour. Use al_lock_bitmap to lock it, then you can use al_get_pixel and al_put_pixel to change colours. Then al_unlock_bitmap when you're done. You can also avoid using al_get_pixel/al_put_pixel and access the memory manually which will be faster. If you lock the bitmap with the format ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE then the memory is laid out like so:
int w = al_get_bitmap_width(bitmap);
int h = al_get_bitmap_height(bitmap);
for (int y = 0; y < h; y++) {
unsigned char *p = locked_region->data + locked_region->pitch * y;
for (int x = 0; x < w; x++) {
unsigned char r = p[0];
unsigned char g = p[1];
unsigned char b = p[2];
unsigned char a = p[3];
/* change r, g, b, a here if they match */
p[0] = r;
p[1] = g;
p[2] = b;
p[3] = a;
p += 4;
}
}
It's recommended that you lock the image in the format it was created in. That means pick an easy one like the one I mentioned, or else the inner part of the loop gets more complicated. The ABGR_8888 part of the pixel format describes the layout of the data. ABGR tells the order of the components. If you were to read a pixel into a single storage unit (an int in this case but it works the same with a short) then the bit pattern would be AAAAAAAABBBBBBBBGGGGGGGGRRRRRRRR. However, when you're reading a byte at a time, most machine are little endian so that means the small end comes first. That's why in my sample code p[0] is red. The 8888 part tells how many bits per component.
I need to get the selection color used by Android to draw ListView and EditText selection. I know these controls user selectors to draw their states, but I've written a few widgets that I want to match the selection color of the platform they are running on and the drawables that are defined can't do that because they are using 9 patch images instead of colors.
I've looked all through the Android source and haven't found a color selector or color constant I can use to get the color I'm looking for.
You could try this :
android:background="?android:attr/selectableItemBackground"
you can get all the resource from here
android-sdk-windows\platforms\android-<Desire API Level>\data\res\drawable-hdpi.
or you can use directly like this
android:background="#android:drawable/list_selector_background"
or like this also
Drawable d = getResources().getDrawable(android.R.drawable.list_selector_background);
Take a look at this answer. You can browse through the platform colors and styles at the Android github mirror. Please note this values can be different for every version of Android. If you want to use platform styles, just don't create your own custom selectors for the controls. Hope it will help.
You could just get the list_selector_background drawable, as explained by Jignesh, and then find its average color as shown in this answer (I'd do it in your initialization code so you don't have to waste processing them every time, but hey, that's premature optimization). That should be consistent enough with the theme to let your widgets match as needed.
Your code could look like this:
public static Color getPlatformSelectionColor(Context c) {
Bitmap bitmap = BitmapFactory.decodeResource(c.getResources(),
android.R.drawable.list_selector_background);
long redBucket = 0;
long greenBucket = 0;
long blueBucket = 0;
long pixelCount = 0;
for (int y = 0; y < bitmap.getHeight(); y++)
{
for (int x = 0; x < bitmap.getWidth(); x++)
{
Color c = bitmap.getPixel(x, y);
pixelCount++;
redBucket += Color.red(c);
greenBucket += Color.green(c);
blueBucket += Color.blue(c);
// does alpha matter?
}
}
Color averageColor = Color.rgb(redBucket / pixelCount,
greenBucket / pixelCount,
blueBucket / pixelCount);
return averageColor;
}
You can achieve easily achieve this for google owned devices but not for other manufacturers as most of the manufacturers have overridden the default colors, layouts, backgrounds, etc for almost all the versions of android including jelly-beans.
So ideally its not recommended and also tough to follow each and everyone's design guidelines.