I'm using Google Maps v2 API for android and I don't manage to control the transparency of the fillColor.
I would like to be able to see the map under a filled polygon.
Is there a way to do that ?
Thanks for any help !
Well, let me describe how standard 4 bytes color is encoded:
Standard pixel color consists of 4 bytes:
A (alpha channel) - 0-255 (0 - fully transparent, 255 - fully opaque)
R (red color channel) - 0-255
G (green color channel) - 0-255
B (blue color channel) - 0-255
Each channel represents the saturation of particular color part. So if we need to create fully opaque red color, we need to specify following channel values:
255,255,0,0
If we want to make it half-transparent, we need to divide alpha channel value by 2 (255/2 = 127):
127,255,0,0
So let's go back to the android. In Android in most cases you can specify color by specifying it's hex value:
polygon.setFillColor(0xFF00FF00); //not transparent green color
In hex every channel can be specified by 2 hex digits:
A(FF)
R(00)
G(FF)
B(00)
If you want to make this color half-transparent, you need to divide FF by 2:
0xFF/2 = 0x7F //the same as 255/2 = 127
polygon.setFillColor(0x7F00FF00); //half-transparent green color
So basically what you need to do - is to play with alpha channel value in order to get transparency you are looking for
cir=map.addCircle(new CircleOptions().center(new LatLng(10.938341, 76.9548734))
.radius(150)
.strokeColor(Color.rgb(0, 50, 100))
.strokeWidth(5)
.fillColor(Color.argb(20, 50, 0, 255))
.zIndex(55));
cir.setVisible(true);
Basically what worked for Me is :
polygon = mGoogleMap.addPolygon(new PolygonOptions().
addAll(points)
.fillColor(0x33FF0000)
.strokeColor(Color.RED)
.strokeWidth(3))
Related
I am trying to define specific gray values in an image. In my application, I create empty bitmaps and generate different patterns on it afterwards(e.g. sinusodial 2D patterns with gray values from 0 - 255 or 0 -1).
In my pevious research I could only find this line of code, that was supposed to solve my poblem:
myBitmap.setPixel(x, y, Color.rgb(45, 127, 0));
But this only tells me how to work with colors, not with gray values.
Does anyone have an idea?
I don't know if there is a way to give an Android bitmap a backing store where each pixel is represented by one byte, but you certainly can set a pixel to gray by setting red, green, and blue values to the same:
int gray = 127; // 0-255
myBitmap.setPixel(x, y, Color.rgb(gray, gray, gray));
I am looking for iOS and Android library for (preferably) or algorithm that would help me to feather edges of the image in similar way how it is handled in Photoshop. The illustration below shows the desired effect of the algorithm. I am not interested feathering bounds of the image, just alpha edges. I have been searching for algorithm that can accomplish it for few days without luck. Any help will be appreciated.
Assuming that you have alpha channel (like on photo with transparent background) it seems that regular convultion blur matrix should satisfy you.
However instead of going through RGB channels - you should go through ALPHA channel only.
Check the blur filter here:
https://en.wikipedia.org/wiki/Kernel_%28image_processing%29
You are interested in box blur/gaussian blur. However to make this effect more smooth - you should use matrix of bigger size.
The reason that algorithm will satisfy your needs is that if all surrounding pixels have alpha 0 - it will be still 0. If 255 - it will stay 255. Just pixels in area of border between alpha 0/255 will be affected.
Edit:
Please check this fiddle with chrome (in ff that's really slow):
http://jsfiddle.net/5L40ms65/
You can take a look into algorithm in the end of code. Since implementation i noted that:
- no need to blur if all neigbour pixels are 255 or 0 (alpha channel)
- it is required to blur also RGB in other case
In general:
RADIUS = 2 (makes total width of matrix = 5)
For x = 0..width
for y = 0..width
if all pixels in square of radius 2 are alpha = 0
do nothing
elsif all pixels in square have alpha = 255
do nothing
else
pixel[x][y].RGB = average RGB of adjacent pixels where alpha != 0
pixel[x][y].ALPHA = average ALPHA in square
Example result with radius=2
Of course this is rather concept program, there is a lot of place for memoization and tuning this script however it should make a big picture clear
You could change the alpha of your border based on the background color of the view.
var r:Float!
var g:Float!
var b:Float!
var a:Float!
if self.view.backgroundColor.getRed(red:r, green:g, blue:b, alpha:a) {
var imgv = UIImageView(frame: CGRect(x:100, y:100, width:100, height:100))
imgv.image = UIImage(named:"name")
imgv.layer.borderWidth = 2.0
imgv.layer.borderColor = UIColor(red:r, green:g, blue:b, alpha:0.5).CGColor
imgv.layer.cornerRadius = imgv.frame.size.width / 2
imgv.clipsToBounds = true
}else{
//Could not get the RGB of background color
}
You may see errors in this code because I have not yet tested it.
currently I'm making an app where user will detect green colors. I use this photo for testing:
My problem is that I can not detect any green pixel. Before I worked with blue color and everything worked fine. Now I can't detect anything though I tried different combinations of RGB. I wanted to know whether it's problem with green or my detection range, so I made an image in paint using (0, 255, 0) and it worked. Why it can't see this circle then? I use this code for detection:
Core.inRange(hsv_image, new Scalar([I change this value]), new Scalar(60, 255, 255), ultimate_blue);
It could have been that I set wrong Range, but I use Photoshop to get color of one of green pixels and convert RGB value of it into HSV. Yet it doesn't work. It don't detect even pixel that I've sampled. What's wrong? Thanks in advance.
Using Miki's answer:
Green color is HSV space has H = 120 and it's in range [0, 360].
OpenCV halves the H values to fit the range [0,255], so H value instead of being in range [0, 360], is in range [0, 180].
S and V are still in range [0, 255].
As a consequence, the value of H for green is 60 = 120 / 2.
You upper and lower bound should be:
// sensitivity is a int, typically set to 15 - 20
[60 - sensitivity, 100, 100]
[60 + sensitivity, 255, 255]
UPDATE
Since your image is quite dark, you need to use a lower bound for V. With these values:
sensitivity = 15;
[60 - sensitivity, 100, 50] // lower bound
[60 + sensitivity, 255, 255] // upper bound
the resulting mask would be like:
You can refer to this answer for the details.
I'd like to ask you what does it do?
a = Color.alpha(pixel);
Is it geting transparency pixel?
And I'd like to ask what is it Dwaring Cache in Android?
Color.alpha get the value of the alpha channel. Android colors are ARGB, integer 32bits, 8 bits per channel. It takes the value of A and it shift this value to the right of 24. Something like
return pixel >>> 24;
Edit: alpha expresses the opacity of your color/pixel. Its range between 0, fully transparent and 255 fully opaque
Google maps api v3 allows "styles" to be applied to the map, including setting the color of various features. However, the color format it uses is HSL (or what seems like it):
hue (an RGB hex string)
lightness (a floating point value between -100 and 100)
saturation (a floating point value between -100 and 100)
(from the docs)
I managed to find RGB to HSL converters online, but I am unsure how to specify the converted values in a way that google maps will accept. For instance, a typical HSL value given by a converter would be: 209° 72% 49%
How does that HSL value map to the parameters I specified from the google maps api? i.e. how does a hue degree value map to an RGB hex string and how does a percentage map to a floating point value between -100 and 100?
I am still uncertain how to do the conversion. I need to, given an RGB value, quickly convert it to what google maps expects so that the color will be identical...
Since the hue argument expects RGB, you can use the original color as the hue.
rgb2hsl.py:
#!/usr/bin/env python
def rgb2hsl(r, g, b):
#Hue: the RGB string
H = (r<<16) + (g<<8) + b
H = "0x%06X" % H
#convert to [0 - 1] range
r = float(r) / 0xFF
g = float(g) / 0xFF
b = float(b) / 0xFF
#http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
M = max(r,g,b)
m = min(r,g,b)
C = M - m
#Lightness
L = (M + m) / 2
#Saturation (HSL)
if L == 0:
S = 0
elif L <= .5:
S = C/(2*L)
else:
S = C/(2 - 2*L)
#gmaps wants values from -100 to 100
S = int(round(S * 200 - 100))
L = int(round(L * 200 - 100))
return (H, S, L)
def main(r, g, b):
r = int(r, base=16)
g = int(g, base=16)
b = int(b, base=16)
print rgb2hsl(r,g,b)
if __name__ == '__main__':
from sys import argv
main(*argv[1:])
Example:
$ ./rgb2hsl.py F0 FF FF
('0xF0FFFF', 100, 94)
Result:
Below is a screenshot showing the body set to a rgb background color (#2800E2 in this case), and a google map with styled road-geometry, using the values calculated as above ('0x2800E2', 100, -11).
It's pretty clear that google uses your styling to create around six different colors centered on the given color, with the outlines being closest to the input. I believe this is as close as it gets.
From experimentation with: http://gmaps-samples-v3.googlecode.com/svn/trunk/styledmaps/wizard/index.html
For water, gmaps subtracts a gamma of .5. To get the exact color you want, use the calculations above, and add that .5 gamma back.
like:
{
featureType: "water",
elementType: "geometry",
stylers: [
{ hue: "#2800e2" },
{ saturation: 100 },
{ lightness: -11 },
{ gamma: 0.5 },
]
}
We coded a tool which exactly does want you want. It takes hexadecimal RGB values and generates the needed HSL code. It comes with a preview and Google Map JavaScript API V3 code output. Enjoy ;D
http://googlemapscolorizr.stadtwerk.org/
From the linked page:
Note: while hue takes an HTML hex color value, it only uses this value to determine the basic color (its orientation around the color wheel), not its saturation or lightness, which are indicated separately as percentage changes. For example, the hue for pure green may be defined as "#00ff00" or "#000100" within the hue property and both hues will be identical. (Both values point to pure green in the HSL color model.) RGB hue values which consist of equal parts Red, Green and Blue — such as "#000000" (black) and "#FFFFFF" (white) and all the pure shades of grey — do not indicate a hue whatsoever, as none of those values indicate an orientation in the HSL coordinate space. To indicate black, white or grey, you must remove all saturation (set the value to -100) and adjust lightness instead.
At least as I read it, that means you need to convert your angle based on a color wheel. For example, let's assume 0 degrees is pure red, 120 degrees is pure blue and 240 degrees is pure green. You'd then take your angle, figure out which two primaries it falls between, and interpolate to determine how much of each primary to use. In theory you should probably use a quadratic interpolation -- but chances are that you can get by reasonably well with linear.
Using that, 90 degrees (for example) is 90/120 = 3/4ths of the way from red to blue, so your hex number for the hue would be 0x00010003 -- or any other number that had green set to 0, and a 1:3 ratio between red and blue.
I needed to match colors exactly. So I used the tool that #stadt.werk offers (http://googlemapscolorizr.stadtwerk.org/) to get close.
But then I ran into the problem explained by #bukzor where the Google Maps API creates variations on your shade, none of which seem to be exactly what I specified.
So I pulled up the map in a browser, took a screenshot of just the area with the two shades that weren't quite matching, opened it up in an image editor (pixlr.com, in my case), used the color-sucker tool to get the saturation and lightness for the shade, adjusted my saturation and/or lightness in the Google API call by 1, and repeated until I got something that seems to match perfectly.
It is possible, of course, that Google Maps API will do different things with the colors on different devices/browsers/etc., but so far, so good.
Tedious, yes, but it works.