Hex transparency in colors [duplicate] - android

This question already has answers here:
Understanding colors on Android (six characters)
(10 answers)
Closed 6 years ago.
I'm working on implementing a widget transparency option for my app widget although I'm having some trouble getting the hex color values right. Being completely new to hex color transparency I searched around a bit although I couldn't find a specific answer to my question.
I want to set transparency by hex color so let's say my hex color id "#33b5e5" and I want it to be 50% transparent. Then I'll use "#8033b5e5" because 80 is 50%.
I found a useful chart here: http://www.dtp-aus.com/hexadeci.htm . With this data I managed to come up with this:
0% = #00
10% = #16
20% = #32
30% = #48
40% = #64
50% = #80
60% = #96
70% = #112
80% = #128
90% = #144
Now the issues start appearing when I get higher than 100 in hex. Hex color codes can only be 8 symbols long right? For example #11233b5e5 (80%) crashes.
What can I do to enable me to use the higher numbers aswell?

Here's a correct table of percentages to hex values for opacity. E.g. for 50% white you'd use #80FFFFFF. To think in terms of transparency instead, flip the order of the percentages (more opaque = less transparent).
%
Hex
100%
FF
95%
F2
90%
E6
85%
D9
80%
CC
75%
BF
70%
B3
65%
A6
60%
99
55%
8C
50%
80
45%
73
40%
66
35%
59
30%
4D
25%
40
20%
33
15%
26
10%
1A
5%
0D
0%
00
(source question)

Short answer: full table of percentages
You can see the full table of percentages to hex values and run the code in this playground in https://play.golang.org/p/l1JaPYFzDkI .
Ok the table tells the results not how to find the results. The next parts explain how you can calculate yourself.
Short explanation in pseudocode
Percentage to hex values
decimal = percentage * 255 / 100 . ex : decimal = 50*255/100 = 127.5
convert decimal to hexadecimal value . ex: 127.5 in decimal = 7*16ˆ1 + 15 = 7F in hexadecimal
Hex values to percentage
convert the hexaxdecimal value to decimal. ex: D6 = 13*16ˆ1 + 6 = 214
percentage = (value in decimal ) * 100 / 255. ex : 214 *100/255 = 84%
More infos for the conversion decimal <=> hexadecimal
Long answer: how to calculate in your head
The problem can be solved generically by a cross multiplication.
We have a percentage (ranging from 0 to 100 ) and another number (ranging from 0 to 255) then converted to hexadecimal.
100 <==> 255 (FF in hexadecimal)
0 <==> 0 (00 in hexadecimal)
For 1%
1 * 255 / 100 = 2,5
2,5 in hexa is 2 if you round it down.
For 2%
2 * 255 / 100 = 5
5 in hexa is 5 .
The table in the best answer gives the percentage by step of 5%.
How to calculate the numbers between in your head ? Due to the 2.5 increment, add 2 to the first and 3 to the next
95% — F2 // start
96% — F4 // add 2 to F2
97% — F7 // add 3 . Or F2 + 5 = F7
98% — F9 // add 2
99% — FC // add 3. 9 + 3 = 12 in hexa : C
100% — FF // add 2
I prefer to teach how to find the solution rather than showing an answer table you don't know where the results come from.
Give a man a fish and you feed him for a day; teach a man to fish and
you feed him for a lifetime

Color hexadecimal notation is like following: #AARRGGBB
A : alpha
R : red
G : green
B : blue
You should first look at how hexadecimal works. You can write at most FF.

I built this small helper method for an android app, may come of use:
/**
* #param originalColor color, without alpha
* #param alpha from 0.0 to 1.0
* #return
*/
public static String addAlpha(String originalColor, double alpha) {
long alphaFixed = Math.round(alpha * 255);
String alphaHex = Long.toHexString(alphaFixed);
if (alphaHex.length() == 1) {
alphaHex = "0" + alphaHex;
}
originalColor = originalColor.replace("#", "#" + alphaHex);
return originalColor;
}

That chart is not showing percents. "#90" is not "90%".
That chart shows the hexadecimal to decimal conversion. The hex number 90 (typically represented as 0x90) is equivalent to the decimal number 144.
Hexadecimal numbers are base-16, so each digit is a value between 0 and F. The maximum value for a two byte hex value (such as the transparency of a color) is 0xFF, or 255 in decimal. Thus 100% is 0xFF.

try this on google search (or click here)
255 * .2 to hex
it will generate 0x33 as a result.
However, google does not round off values so you can only use 1-digit multipliers. if you want to use say .85, you have to get the rounded-off value of 255 * .85 first, then type (rounded-value here) to hex in google search.

I realize this is an old question, but I came across it when doing something similar.
Using SASS, you have a very elegant way to convert RGBA to hex ARGB: ie-hex-str. I've used it here in a mixin.
#mixin ie8-rgba ($r, $g, $b, $a){
$rgba: rgba($r, $g, $b, $a);
$ie8-rgba: ie-hex-str($rgba);
.lt-ie9 &{
background-color: transparent;
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#{$ie8-rgba}', endColorstr='#{$ie8-rgba}');
}
}
.transparent{
#include ie8-rgba(88,153,131,.8);
background-color: rgba(88,153,131,.8);
}
outputs:
.transparent {
background-color: rgba(88, 153, 131, 0.8);
}
.lt-ie9 .transparent {
background-color: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#CC589983', endColorstr='#CC589983');
zoom: 1;
}

I always keep coming here to check for int/hex alpha value. So, I end up creating a simple method in my java utils class. This method will convert the percentage of transparency to hex value and append to the color code string value.
public static String setColorAlpha(int percentage, String colorCode){
double decValue = ((double)percentage / 100) * 255;
String rawHexColor = colorCode.replace("#","");
StringBuilder str = new StringBuilder(rawHexColor);
if(Integer.toHexString((int)decValue).length() == 1)
str.insert(0, "#0" + Integer.toHexString((int)decValue));
else
str.insert(0, "#" + Integer.toHexString((int)decValue));
return str.toString();
}
So, Utils.setColorAlpha(30, "#000000") will give you #4c000000

Related

Android Round method has bug that doesnt round correct

Today while i am coding in Android, i find out a bug in Android and couldnt find possible way to handle it.
Question is
int PERT = Math.round(100 * (Total - StokAdet) / Total);
Everything is pretty good but when Total is 12 and StokAdet is 10, then something magicly happens and result brings me 16.
Normally the result is 16.6666667 but when rounded it must become 17.
But it returns 16.
I hope to hear you. Thanks..
I'm guessing it's because you are doing an integer division here. So 100 * (Total - stokAdet) / Total is 16 already. Probably because Total and StokAdet are ints.
So if we evaluate it step by step as java would:
Total - StokAdet = 12 - 10 = 2
100 * (Total - StokAdet) = 100 * (12 - 10) = 200
100 * (Total - StokAdet) / Total = (100 * (12 - 10)) / 12 = 16
This last bit might seem odd because it should be 16.66666...7 by normal arithmetic right? Well because we are in Java and all of the numbers are integers the output will also be an integer. Integers can't represent the bit after the decimal point (the ".66666...7" bit). Now it might seem crude but what Java does is it just throws away the ".66666...7" bit so 16.66666...7 becomes just 16.
However if either the Total or StokAdet were float values then the calculation would give you your number as expected.
This is fine:
int PERT = Math.round(100 * (Total - StokAdet) / Total);
Just add this below
int i = Math.round(PERT);
Then i is the rounded number.
It's not a bug, it's a feature. H.Brooks answer shows how to get around it.
Why? You are are working in integers. And integers are not rounded up or down with division. They are cut off. In Java, int 1.9999999999999 is always going to be 1, not 2. So take a moment to pick the right variable for the right value.
Further reading: Division of integers in Java

File access and retrieval within an android library

There must be some sort of small technical error that I am performing here that I cannot get a grasp on. The file is in the raw/ directory of the AndroidLibrary, and access to different files are being used just fine in this manner. Perhaps there is a slight error here that I keep glazing over?
Note: The raw resource is in an uncompressed format so that it can be read in with a .jet extension so that there are not any complaints by the internal file system.
Edit (Update): Apparently in order to get the stream open, the openRawResourceFd was not enough. In addition to that I needed to call assetDescriptor.createInputStream(); If I did not, the stream would not behave properly. Odd, as I would expect the openRawResourceFd to do the trick.
AssetFileDescriptor assetDescriptor = resources.openRawResourceFd(com.grubulon.R.raw.testing_patches);
BufferedReader bufferedInputStream = new BufferedReader(new FileReader(assetDescriptor.getFileDescriptor()));
colorSpace = bufferedInputStream.readLine();
while ((currentLine = bufferedInputStream.readLine()) != null)
{
rgbValues = currentLine.split("\\t");
red = Integer.parseInt(rgbValues[0]);
green = Integer.parseInt(rgbValues[1]);
blue = Integer.parseInt(rgbValues[2]);
rgbPatches.add(new RgbColorValue(red, green, blue));
}
bufferedInputStream.close();
assetDescriptor.close();
The file itself is really only an Excel spreadsheet of RGB color values that are being read in with tabs in between them. The tab component does not seem to be the issue, but the first line is a garble of lots and lots of text. Not the color space, or values at all for that matter. I am not sure what is going on here.
File example:
RGB
0 0 0
17 17 17
34 34 34
51 51 51
68 68 68
85 85 85
102 102 102
119 119 119
136 136 136
153 153 153
170 170 170
187 187 187
204 204 204
221 221 221
238 238 238
255 255 255
255 0 0
0 255 0
0 0 255
The following is an example of what is coming across in the Logcat even though there should be very little text coming across from the file.
The following based upon the update above is what has resolved the problem. Notice the line after the assetDescriptor is created with the openRawResourceFd call.
AssetFileDescriptor assetDescriptor = resources.openRawResourceFd(com.grubulon.R.raw.testing_patches);
assetDescriptor.createInputStream();
BufferedReader bufferedInputStream = new BufferedReader(new FileReader(assetDescriptor.getFileDescriptor()));
colorSpace = bufferedInputStream.readLine();
while ((currentLine = bufferedInputStream.readLine()) != null)
{
rgbValues = currentLine.split("\\t");
red = Integer.parseInt(rgbValues[0]);
green = Integer.parseInt(rgbValues[1]);
blue = Integer.parseInt(rgbValues[2]);
rgbPatches.add(new RgbColorValue(red, green, blue));
}
bufferedInputStream.close();
assetDescriptor.close();

How to convert WiFi level (i.e. -45 , -88 ) in to percentage?

How to convert WiFi level (i.e. -45 , -88 ) in to percentage ?
I want to convert WiFi level in % . I get WiFi level using level ( in dBm format)
I try lot of google but not get proper ans
Problem with this is that is very dependent on the receiving antenna. Some antennas register no useable signal at -90 dBm, some already at -80. You will have a hard time finding 0% (100% strictly being 0dBm).
I have created a Wifi scanner application where I use -100dBm as 0% and 0dBm as 100%, in Java it turns into something like this (MIN_DBM being -100):
public int getPowerPercentage(int power) {
int i = 0;
if (power <= MIN_DBM) {
i = 0;
} else {
i = 100 + power;
}
return i;
}
This is what Microsoft does for dBm <> percent conversion:
https://stackoverflow.com/a/15798024/2096041
Basically -50 .. 0 dBm maps linear to 100 .. 0 %.
Like MS, i would prefer to sit on the safe side and not use -100 as 100% as some answers here suggest.
The WifiManager class has a function calculateSignalLevel, but as it states here, it results in an error if numLevels is greater than 45. Possible workaround could be something like this:
double percentage = WifiManager.calculateSignalLevel(int rssi, 40) * 2.5;
but of course, this will be in steps of 2.5 percents - I don't know your use case but maybe this is sufficient.
As others have stated, calculating percentages is problematic, and there's no simple precise solution for that.
You could derive the percentage from the signal-to-noise ratio, rather than the signal intensity alone, if this information is available. This is probably the desired metric.
An android.net.wifi.ScanResult does not publish the neccessary information (as of Dec 2012), but you might be able to get this information through other means.
Signal = Noise => unusable signal, so you could set 0dB SnR = 0%. Also you could set 10dB SnR to 90% (90% of the signal power is not drowned out in noise), and 100% = no noise at all. More generally,
p = 100% * (1 - 10^(SnR / (10dB)))

Polar Wearlink Bluetooth packet

i am looking at the code of a project called MyTracks:
http://code.google.com/r/jrgert-polar-bluetooth/source/browse/MyTracks/src/com/google/android/apps/mytracks/services/sensors/PolarMessageParser.java?r=ebc01faf49550bc9801633ff38bb3b8ddd6f5698
Now I am having problems with the method isValid(byte[] buffer). I don´t understand what exactly is he checking here. We want to know if the first byte in the array is the header containing 0xFE. I don´t quite understand the following lines :
boolean goodHdr = ((buffer[0] & 0xFF) == 0xFE);
boolean goodChk = ((buffer[2] & 0xFF) == (0xFF - (buffer[1] & 0xFF)));
return goodHdr && goodChk;
any ideas?
Ewoks is correct, refer to this blog post:
http://ww.telent.net/2012/5/3/listening_to_a_polar_bluetooth_hrm_in_linux
"Digging into src/com/google/android/apps/mytracks/services/sensors/PolarMessageParser.java we find a helpful comment revealing that, notwithstanding Polar's ridiculous stance on giving out development info (they don't, is the summary) the Wearlink packet format is actually quite simple.
Polar Bluetooth Wearlink packet example
Hdr - Len - Chk - Seq - Status - HeartRate - RRInterval_16-bits
FE - 08 - F7 - 06 - F1 - 48 - 03 64
where
Hdr always = 254 (0xFE),
Chk = 255 - Len
Seq range 0 to 15
Status = Upper nibble may be battery voltage
bit 0 is Beat Detection flag."
&0xff simply converts signed byte to unsigned int for doing the comparison
First line is checking is received buffer are starting with 0xFE as it should be with this Polar Wearable.
Second line is checking if length byte is correct as well because it's value by specification is 255-value writen is size byte..
This together is super simple verification that messages are correct (more complicated implementation would include CRC or other verification methods). cheers

SMS text counter in Android

I want to implement SMS text counter like feature as in Android default messaging application. So that after each 161 character counter should be incremented by one and on deleting of character it should decrease.
Math.floor(chars / 160) + 1
This will divide the number of characters you have by the SMS-limit (160), cut off the decimal place and add "1".
http://www.java-examples.com/find-floor-value-number-using-math.floor
e.g. chars = 170, then (chars / 160) = 1,0625 and floor(1,0625) = 1, the result would be that 170 characters mean 2 SMS.
Something like:
int countSMS = (nbOfCharacters / 160) + 1;

Categories

Resources