Calculating color shades - php

I have the next problem.
I have a base color with couple of different shades of that color.
Example:
Base color: #4085c5
Shade: #005cb1
Now, I have a different color (let's say #d60620), but no shades of it. From the color I would like to calculate shades, that have similar difference as colors mentioned in first paragraph.
First I tried calculating difference of RGB elements and applying them to second color, but the result was not like I expected to be.
Than I tried with converting color to HSV, reading saturation value and applying the difference to second color, but again the resulting color was still weird.
The formula was something like: (HSV(BaseColor)[S] - HSV(Shade)[S]) + HSV(SecondColor)[H]
Does anyone know how this problem could be solved? I know I am doing something wrong, but I don't know what. :)

There are two ways to darken a color:
Subtract an equal amount from R,G,B. This increases the saturation. Obviously you can only subtract an mount equal to the least of the R,G,B values.
Multiply R,G,B by a value less than 1.0. This leaves the saturation more or less intact.
Similarly, there are two ways to lighten a color:
Add an equal amount to R,G,B. This decreases the saturation.
Multiply R,G,B by a value greater than 1.0. This increases the vividness of the color and thus the apparent saturation.
Your example appears to have done both - subtracting 0x40 from each value and multiplying by 1.33.
Using your second color, we can subtract 06 from each resulting in #d0000a but this is not dark enough. Multiplying it by 0.735 results in #990013.

Your first two colours both have a "H" (hue) value of 209, and varying values for "S" and "V".
This common hue is what defines the second colour as being a "shade" of the first colour.
To find alternative shades of your third colour, use an RGB to HSV conversion to find its hue, modify its S and V values as desired, and then convert back to RGB.

Related

How to convert artbitrary number to rgb color?

I have an application that has about one hundred users. We have a calender view in which every user can have multiple entries. Every entry of the same user should have the same color, but different users should have different colors. At the moment we have manually defined about 25 colors in an array, and the color a user gets is determined by
$color = $colors[$userid % count($colors)];
We don't want to manually add colors for every new user, and selecting a color for each user seems a bit tedious too.
Is there a simple function to map a number (the users id) to a color (preferably RGB)? The next question that rises is; Is there a way to limit the function to a certain types of colors (ie. only colors in which white letters are readable)?
I don't have a solution, per se, but a suggestion.
First, since you want each user's colors to be unique but random, you could get started with some kind of numerical hash function. That gets you a random number that's most likely unique. if your hash function is decent and your users are in the hundreds that should suffice.
Now you need to turn that into colors, preferably on the dark end of the spectrum. If you go with RGB, You need three numbers. To keep them dark, lets say you keep the total or R, G and B under 200. That's a guess, of course, but it should be pretty dark. Pick a random number [index] between 1 and 3 - that's the R, G or B you're going to start with. Get a number between 0 and 200, and set record it for color[index1]. Now pick one of the remaining indexes, 1-3. For this, pick a number between 0 and color[index1] that you already have. Set the remaining number to 200-color[index1]-color[index2]. Now you have a randomish RGB value that should contrast with white.
I realize I never got much use from that hash function up front - maybe ditch it and just use the userid as a random(seed).
You want to work in the hue-saturation-lightness or hue-saturation-value (HSL or HSV) space.
http://en.wikipedia.org/wiki/HSL_and_HSV
Start by defining some colors based on hue and saturation, and set the lightness to the highest tolerable level that makes the text readable.
Then you can fix the hue and saturation for these colors and decrease the lightness.
So say you started by choosing 25 tolerable colors with different hues and maximum/minimum tolerable lightness.
To generate a color for an index you pick the base color to start with base = id % 25 You then decrease the luminance depending on the index within that color index = (Math.floor(id/25)). Set the luminance somewhere within the tolerable luminance range based on that value. So let's say we will have 5 luminance values per color, set the luminance to
lightness = maxLightness - index*(maxLightness / 4*minLightness)
This simply varies the lightness for each color. You can choose to vary saturation and hue slightly if you would prefer. Converting between HSV and RGB is a well documented procedure.
PHP HSV to RGB formula comprehension

Arranging four points as a square

This is prob more of a geometry question, but
I have an array of 4 points (from user input), that could be in any order.
I'm trying to work out a procedure that would return what each point is likely to be, i.e.
top left,
top right,
bottom left,
bottom Right
I'm working in PHP now, but any help in any language is fine.
{'Ill add what i've got so far in PHP shortly}
Would this question be better asked on another stackexchange, math maybe?
You could sort the points by their x coordinates ascending and if there's a tie, the y coordinate ascending.
The first two points are the "left" side - the one with the greater y is the "top" and the other is "bottom".
The last two points are the "right" side, same deal.
This won't work for a diamond though! (But what's "top-left" on a diamond anyway?)
In general, for a convex set of points, you can calculate the centroid (x value is the average of all x values, y value is the average of all y values).
Then, you can calculate the argument (i.e. angle) of the line between the centroid and the point, being arctan2 of (y_pt-y_centroid,x_pt-x_centroid).
If you then sort the points by their arguments, they'll be in anticlockwise order, with -pi being the West point of the compass, 0 being the East, wrapping around again to +pi being the west point.
You could sort the points first vertically and call the top 2 points top points and the bottom 2 bottom points. Then sort the points horizontally and call the two right-most points right and the other two left. Now you have one of each.
The two-points with the lowest x-values make up the left-side, the other two make up the right.
Same goes for y and top/bottom.

logic of color variance

http://dribbble.com/colors/1a15a1?percent=5&variance=50
I understand the color minimum slider--you would count the color of each pixel, then create a ratio for a particular color based on the total pixels of the image (10 blue:100 total) = 10% blue.
But what's the logic behind the color variance slider? Looking at the RGB values of these colors http://en.wikipedia.org/wiki/Web_colors#X11_color_names some patterns are apparent, but imagining a sql table full of pictures and their pixel data, anyone have an idea on how to calculate variance?
I too think you are right for the color minimum. Color variance is easy too. If you select a small variance you will get images with a small count of colors used on it. Logically 0% variance must bring an image of a single color only.
I don't think you have to store pixels at all, logically for storing a new image it goes like this:
Read image file
Find how many different color there are in it
Store image path and number of different colors on it.
Then on retriving the image would go like this:
Ask the user what variance he likes
Let's say variance = 60%
Read distinct maximum numbers of colors for an image
MaxColors = 100% (let's say max=18 colors per image)
Turn 60% to integer
18 = 100%
x = 60% then
18*60=100*x then 100*x=1080 then x=10.8
Make 10.8 round so it becomes x=11
Retrieve from database all images that have 11 or more colors on them
Display these images as the result
So no need to store any pixel at all, just a single integer that indicates how many colors consist of an image.

sorting images by color

I'm looking for a way to sort images as in the following screenshot:
http://www.pixolution.de/sites/LargeImages_en.html
I've looked at all the threads on this topic on stackoverflow but none of the proposed solutions even come close to giving me the image above.
Approaches I've tried:
for each image, build histogram of rgb colors in descending order of occurrence
for each histogram, calculate a distance from black (r:0,g:0,b:0) as follows:
for color in image_histogram:
total_distance += color.percentage_of_image * distance(BLACK_RGB, color.rgb)
then sort images by their distances
I was hoping that images of similar color distribution would end up with a similar distance and result in a visual ordering by color. This was not the case, it seems to somewhat work but not like in the image above.
For the distance function, I've tried euclidean distance, hsv sorting (h->s->v) and even Lab distance sorting. None of which has helped
If anyone has a better approach, I would love to know!
I've never done something like this myself, so forgive me if the following approach is naive:
For each image, boil it down to 1 average RGB value by summing the R, G, B values of all pixels, and divide by the total # pixels. Normalize the components to [0..1]
Plot the image in your 2D color space based on the RGB values. This can be a 2D projection of a 3D (r, g, b) vector transformation.
you could convert to HSV and sort by H
Hue is what most people think of when they think "color"
see: RGB to HSV in PHP
Group similar colors using the distance between them and not between them and black, and use the average color in the image.
You might want to check out ImagePlot. I'm not sure if the algorithms behind the system are available, but you can certainly download and run your image collection through the free software to analyze them.
This software is used in many interesting visualizations of massive image collections, millions+
Info: http://lab.softwarestudies.com/p/imageplot.html#whatsnew
Source: https://github.com/culturevis/imageplot

PHP Color Manipulation

I am currently looking into color manipulation / selection etc and have come across the following piece of code. I was wondering of someone could tell me what the following piece of code is doing and break it down for me thanks!
$newVal = round(round(($rgb['red'] / 0x33)) * 0x33);
In particluar what is the 0x33
Thanks in adavnce
It seems to be converting $rgb['red'] the nearest multiple of 0x33.
It's probably doing that so the color will end up on the so-called "web safe" color palette, which (if I recall correctly) consists of colors who's rgb values are multiples of 0x33.
0x33 is the base-16 (hex) representation of 51 (decimal).
0x33 is 51, so it scales the 0-255 value of a single byte to 0-5, and then scales it back out. This results in the value being floored to the highest multiple of 51 lower than the value.
0x33 is just hex value for 33.
I'm not really sure what is happening, but my guess would be it calculates a web safe hex of any color. Or something along these lines.
As #Seth indicated, it's rounding colours to the nearest 'web-safe' colour. It's an old idea, dating from back when most colour displays were 8-bit. One of the people to make it popular was Visibone as their 'websafe colour chart' was their first product.
See Web Colours for more information.

Categories