How to use HSLA colors with RMagick? - colors

How to set an arbitrary HSLA color instead of gray20?
draw = Magick::Draw.new
draw.font_family = 'arial'
draw.pointsize = 12
draw.gravity = Magick::CenterGravity
draw.annotate(#canvas, size,size, x,y, text) { self.fill = 'gray20' }
Also, using gc.rectangle, how to set the HSLA color of the fill?
gc = Magick::Draw.new
gc.fill ????
gc.rectangle(x,y, x + size,y + size)

From the RMagick documentation:
Many RMagick methods expect color name arguments or return color names. A color name can be
an X11 color name such as "red", "chocolate", or "lightslategray".
an SVG color name (similar to the X color names), or
a string in one of the formats shown in the following table.
...
hsla(h,s,l,a)
And HSL documentation
hsla(33.3333%, 100%, 50%, 1.0) green with an alpha value of 1.0
hsla(120, 255, 127.5, 1.0) green with an alpha value of 1.0
So, use a string: fill 'hsl(0%,100%,100%,1)'

Related

How to fill cell with 50% intensity of an hexadecimal color using openpyxl

I'm using openpyxl with python 3.10 to create a xls file from a dataBase.
I extract an hexadacimal color from this dataBase and I want to fill cells with this color but only with 50% intensity. Currently, i have this :
import sqlite3, openpyxl
def getRouteColor(route):
cursor.execute('''SELECT route_color
FROM routes
WHERE route_short_name = "{}"'''.format(route))
return cursor.fetchall()[0][0]
[...]
color = getRouteColor(route) #hexadecimal
for column in sheet.columns:
for cell in column:
if not cell.row % 2:
cell.fill = openpyxl.styles.PatternFill(patternType = 'solid', fgColor = color)
I've try to use different patternType to lower intensity but it wasn't conclusive because I don't want lines or dots.
Do you have any ideas of how to get a 50% intensity (using openpyxl, or other way like get a 50% intensity hexadecimal code from the 100% intensity hexadecimal code) ?
I have found a way to do it :
I convert my hexadecimal color to RGB color and apply an alpha of 0.5 to it. Then, I convert it back to hexadecimal :
def color50(color): #color : hexadecimal 'XXXXXX'
rgb = tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
rgb50 = []
for i in rgb :
rgb50.append(int(0.5 * i + (1 - 0.5) * 255))
return '{:X}{:X}{:X}'.format(rgb50[0], rgb50[1], rgb50[2])
If you have a better way to do it I'm still interested

Setting color variable

I need to compare colors. I want to set a color into a variable and then compare that it a value obtained using getPixel.
However, the following does not work. It seems like ImageJ does not know that the value in basecolor is a color.
basecolor = 0xFFFFFF;
rightpixel = getPixel(x, y);
if (rightpixel == basecolor) count++;
Your problem is in getPixel which does not yield a color written in hex.
I present to you your best friend on ImageJ : the built-in macro functions code
https://imagej.nih.gov/ij/developer/macro/functions.html
which documents built-in pixel functions such as getPixel().
For getPixel(), it is stated "Note that pixels in RGB images contain red, green and blue components that need to be extracted using shifting and masking. See the Color Picker Tool macro for an example that shows how to do this. ", and the Color Picker Tool macro tells us how to go from color "bits" to RGB.
So if you wish to compare colors, you do :
basecolor=newArray(0,0,0);
rightpixel = getPixel(x,y);
//from the Color Picker Tool macro
//converts what getPixel returns into RGB (values red, green and blue)
if (bitDepth==24) {
red = (v>>16)&0xff; // extract red byte (bits 23-17)
green = (v>>8)&0xff; // extract green byte (bits 15-8)
blue = v&0xff; // extract blue byte (bits 7-0)
}
//compare the color with your color
if(red==basecolor[0] && green==basecolor[1] && blue==basecolor[2]){
print("Same Color");
count++;
}
//you can also work with hex by converting the rgb to hex and then
//comparing the strings like you did

Don't understand hsv color palette

i test a lot converters hex to hsv rgb to hsv and other options. But don't understand situation i have paint program which i see use HSV palette. i use TinyColor converter. I don't know why i sometimes get good color, sometimes not good.
This return good result red color:
var color = tinycolor("#FF0000"); //red
color.toHsv(); // return { h: 0, s: 1, v: 1 }
This return bad result not yellow color:
var color = tinycolor("#FFFF00"); //yellow
color.toHsv(); // return { h: 60, s: 1, v: 1 } and i get not yellow color
If i write in my hsv input like this:
h: 0.16
s: 1
v: 1
i get yellow collor WTF?
I see in my HSV palette i can write only one digit numbers like this:
1, 0.1, 0.99, max is 1 min is 0.00
Hue, the h in hsv, is traditionally expressed in degrees around a circle — the color wheel, which means it can have a value from 0º - 360º. See: http://en.wikipedia.org/wiki/Hue
It is sometimes convenient to express this as a percentage instead where 0= 0º, 0.5 = 180º, 1.0 = 360º, etc. The documentation for TinyColor explains that it will accept either input, but it is not clear what its default output is (at least from my quick scan).
It seem to be returning degrees, but your other application is expecting a percentage. A 60º hue is yellow, but you may need need to convert to a percentage for whatever application you're using with the hsv palette.
In this particular case, 60º/360º = 0.1667

Convert RGB to RGBA

I am trying to play with HTML5 canvas, and I want to get the color of the fillStyle right from my CSS, but also with some transparency. When I use jQuery to read CSS style, a rgb value is returned instead of hex.
fillColor = $(".myClass").css("background-color"); // return rgb(x, x, x)
At first it look it's convinient to me that I don't need to convert it again, but I find that I cannot add the alpha to the RGB value, so I have to convert it into Hex, then convert it to RGBA with an alpha value.
function convertHexToRGB(hex)
{
var red = hex.substr(1, 2), green = hex.substr(3, 2), blue = hex.substr(5, 2), alpha = arguments[1];
color = "rgba(" + parseInt(red, 16) + "," + parseInt(green, 16) + "," + parseInt(blue, 16) + "," + alpha + ")";
return color;
}
Now that make my code looks stink and inefficient, is there any way to add a alpha value to a RGB value. Or some function that converts RGB to RGBA?
Couldn't you just retrieve the opacity value from your css like this:
fillOpacity = $(".myClass").css("opacity"); // return 0.x
And then translate the opacity value into the 'A' channel you need:
var alpha = fillOpacity * 255;
And then append that to you rgb value (in int form)?
EDIT:
I should mention that the HTML5 canvas element works with bitmaps effectively so whilst you can do some combination bits and bobs, so there is no direct concept of layers, in that you can't (as far as I'm aware) tell a canvas element to be r,g,b,a because there is nothing for it to combine with underneath. Unless of course you are trying to place a semi-opaque canvas over a background image of some form. Or, combine an underlying image via say, multiply blending with your original CSS colour, to achieve the affect of a semi-transparent layer over an image.

Given an RGB value, how do I create a tint (or shade)?

Given an RGB value, like 168, 0, 255, how do I create tints (make it lighter) and shades (make it darker) of the color?
Among several options for shading and tinting:
For shades, multiply each component by 1/4, 1/2, 3/4, etc., of its
previous value. The smaller the factor, the darker the shade.
For tints, calculate (255 - previous value), multiply that by 1/4,
1/2, 3/4, etc. (the greater the factor, the lighter the tint), and add that to the previous value (assuming each.component is a 8-bit integer).
Note that color manipulations (such as tints and other shading) should be done in linear RGB. However, RGB colors specified in documents or encoded in images and video are not likely to be in linear RGB, in which case a so-called inverse transfer function needs to be applied to each of the RGB color's components. This function varies with the RGB color space. For example, in the sRGB color space (which can be assumed if the RGB color space is unknown), this function is roughly equivalent to raising each sRGB color component (ranging from 0 through 1) to a power of 2.2. (Note that "linear RGB" is not an RGB color space.)
See also Violet Giraffe's comment about "gamma correction".
Some definitions
A shade is produced by "darkening" a hue or "adding black"
A tint is produced by "ligthening" a hue or "adding white"
Creating a tint or a shade
Depending on your Color Model, there are different methods to create a darker (shaded) or lighter (tinted) color:
RGB:
To shade:
newR = currentR * (1 - shade_factor)
newG = currentG * (1 - shade_factor)
newB = currentB * (1 - shade_factor)
To tint:
newR = currentR + (255 - currentR) * tint_factor
newG = currentG + (255 - currentG) * tint_factor
newB = currentB + (255 - currentB) * tint_factor
More generally, the color resulting in layering a color RGB(currentR,currentG,currentB) with a color RGBA(aR,aG,aB,alpha) is:
newR = currentR + (aR - currentR) * alpha
newG = currentG + (aG - currentG) * alpha
newB = currentB + (aB - currentB) * alpha
where (aR,aG,aB) = black = (0,0,0) for shading, and (aR,aG,aB) = white = (255,255,255) for tinting
HSV or HSB:
To shade: lower the Value / Brightness or increase the Saturation
To tint: lower the Saturation or increase the Value / Brightness
HSL:
To shade: lower the Lightness
To tint: increase the Lightness
There exists formulas to convert from one color model to another. As per your initial question, if you are in RGB and want to use the HSV model to shade for example, you can just convert to HSV, do the shading and convert back to RGB. Formula to convert are not trivial but can be found on the internet. Depending on your language, it might also be available as a core function :
RGB to HSV color in javascript?
Convert RGB value to HSV
Comparing the models
RGB has the advantage of being really simple to implement, but:
you can only shade or tint your color relatively
you have no idea if your color is already tinted or shaded
HSV or HSB is kind of complex because you need to play with two parameters to get what you want (Saturation & Value / Brightness)
HSL is the best from my point of view:
supported by CSS3 (for webapp)
simple and accurate:
50% means an unaltered Hue
>50% means the Hue is lighter (tint)
<50% means the Hue is darker (shade)
given a color you can determine if it is already tinted or shaded
you can tint or shade a color relatively or absolutely (by just replacing the Lightness part)
If you want to learn more about this subject: Wiki: Colors Model
For more information on what those models are: Wikipedia: HSL and HSV
I'm currently experimenting with canvas and pixels... I'm finding this logic works out for me better.
Use this to calculate the grey-ness ( luma ? )
but with both the existing value and the new 'tint' value
calculate the difference ( I found I did not need to multiply )
add to offset the 'tint' value
var grey = (r + g + b) / 3;
var grey2 = (new_r + new_g + new_b) / 3;
var dr = grey - grey2 * 1;
var dg = grey - grey2 * 1
var db = grey - grey2 * 1;
tint_r = new_r + dr;
tint_g = new_g + dg;
tint_b = new_b _ db;
or something like that...

Resources