Calculate RGB use intensity - java

I was making a Gauroud algorithm and when i had calculated point intensity on the edge I didn't know what to do with it. I tried to decide this problem like:
private int getPointRGB(double intensity)
{
float[] hsb=null;
double newCrRed;
double newCrGr;
double newCrBlue;
int nRGB;
//crRed, crGr, crBlue - primary components of edge RGB
newCrRed = intensity*crRed;
newCrGr = intensity*crGr;
newCrBlue = intensity*crBlue;
hsb = Color.RGBtoHSB((int)newCrRed, (int)newCrGr, (int)newCrBlue, null);
nRGB = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
return(nRGB);
}
am I right?

If none of the default color choosers are satisfactory, you can create your own custom chooser panel, as discussed in How to Use Color Choosers: Creating a Custom Chooser Panel. For example, you could implement the CIE 1976 color space, shown here.

Related

Is it possible to select/click multiple parts of one image?

For an assignment I am making a Boardgame. (In java) This Boardgame has a map, with multiple fields/lands that have to be used. Units can be placed on them, they can move. Other things are also placed on them.
For the map I have one image I use. I looked online for solutions, but the only ones I found where for a grid game (such as chess or checkers) and the map of this game can not be divided in just squares. I tried this, but the field shapes are to different to make that work.
I had a few faint ideas as to how to work this out, but I can't quite put them into code examples and have no clue if they would work, or how.
The ideas I had:
Make some invisible buttons and bind them to specific coordinates in the picture. The problem I had with this solution was that it also had to be able to display things placed on it. It would also be very inconvenient if not all of the field was clickable.
I have a 'overlay' image with the outlines of all the fields and the 'insides' removed. I made this overlay so I could add a faint color overlay over the board. Would it be possible to use this in any kind of way?
First I though of cutting out all the loose fields and putting them together to form the one image. Only, I don't know how I would do this. Not just where to place it, but also, how can I make sure that the elements are Always in the same place compared to eachother, and my board doesn't mess up when changing screen/resolution size?
I am using javafx for the graphical elements in my game.
If there are any suggestions of something I haven't thought of myself, those are also very welcome.
If it's sufficient to retrieve the color of the pixel where the mouse was clicked, then you can do that fairly easily. If you know the image is displayed in the image view unscaled and uncropped, then all you need is:
imageView.setOnMouseClicked(e -> {
Color color = imageView.getImage().getPixelReader().getColor((int)e.getX(), (int)e.getY());
// ...
});
More generally, you may need to map the image view coordinates to the image coordinates:
imageView.setOnMouseClicked(e -> {
double viewX = e.getX();
double viewY = e.getY();
double viewW = imageView.getBoundsInLocal().getWidth();
double viewH = imageView.getBoundsInLocal().getHeight();
Rectangle2D viewport = imageView.getViewport();
double imgX = viewport.getMinX() + e.getX() * viewport.getWidth() / viewW;
double imgY = viewport.getMinY() + e.getY() * viewport.getHeight() / viewH ;
Color color = imageView.getImage().getPixelReader().getColor((int)imgX, (int)imgY);
// ...
});
Once you have the color you can do some simple analysis to see if it approximately matches the color of various items in your image, e.g. check the hue component, or check if the "distance" from a fixed color is suitably small.
A typical implementation of that might look like:
// choose a color based on what is in your image:
private final Color FIELD_GREEN = Color.rgb(10, 10, 200);
private double distance(Color c1, Color c2) {
double deltaR = c1.getRed() - c2.getRed();
double deltaG = c1.getGreen() - c2.getGreen();
double deltaB = c1.getBlue() - c2.getBlue();
return Math.sqrt(deltaR * deltaR + deltaG * deltaG + deltaB * deltaB);
}
private boolean colorsApproximatelyEqual(Color c1, Color c2, double tolerance) {
return distance(c1, c2) < tolerance ;
}
And the back in the handler you can do
if (colorsApproximatelyEqual(color, FIELD_GREEN, 0.1)) {
// process click on field...
}
Whether or not this is a viable approach depends on the nature of the image map. If the coloring in the map is too complex (or objects are not easily distinguishable by color), then you will likely need to place other elements in the scene graph and register handlers on each of them, as you describe in the question.

Generate n colors between two colors

I'm trying to write function, which can generate colors between two colors based on a given value. An example would explain it better..
Input ..
X : 1
Y : 0.5
Z : 0
The user gives any set of color:value pairs, then enters a number(say 0.75). I have to then generate color which is a blend of Y and Z in proportion(based on the their values and the input value). I was thinking of the following approach.
Find the colors which surround the value, for 0.75 it will be 0.5 and 1.
Mix those two colors somehow, based on the value and generate new colors.
I'm completely lost, as how to generate colors and are there any libraries for this.
UPDATE:
It is part of a bigger project I'm working on. Lets say we have ..
1 : X
0 : Y
and the user inputs, 0.25
I would like to have something..
(X*0.25 + Y*0.75)
as it's more near to Y, that's why the higher proportion. If the user inputs, 0.5.. the output should be
(X*0.5 + Y*0.5)
and so on. I have no idea how to do this with RGB colors.
P.S: The questions is not specific to language, but I'm doing this in Java.
You have to blend each color channel (red, green and blue) seperately like this:
Color x,y; //set by you
float blending;//set by you
float inverse_blending = 1 - blending;
float red = x.getRed() * blending + y.getRed() * inverse_blending;
float green = x.getGreen() * blending + y.getGreen() * inverse_blending;
float blue = x.getBlue() * blending + y.getBlue() * inverse_blending;
//note that if i pass float values they have to be in the range of 0.0-1.0
//and not in 0-255 like the ones i get returned by the getters.
Color blended = new Color (red / 255, green / 255, blue / 255);
So far for the color example. Generally if you want a linear interpolation between two values you have to do the following:
var firstValue;
var secondValue;
var interpolation;
var interpolated = firstValue * interpolation +
secondValue * (1 - interpolation);
But since you have Color-Objects in your case, you cannot interpolate the whole object in one step, you have to interpolate each relevant value on its own. Eventually you have to interpolate the alpha-channel as well, don´t know that, since you didn´t mention it, but for completeness i include it in this answer.
A color is a point in a three-dimensional space. The exact coordinates used depend on what's called a "color space", of which there are several: RGB, HSV, and so on. So to compute a color in between two given colors, get those two colors in the same color space, and compute a third point between those two along the line in 3d-space between them.
The simplest way to do this would be simply to do a linear interpolation for each of the three values of the colorspace (R, G, and B, for example). But there's a further complication that the coordinate values are often not linear, so you have to linearize them first (for example, TV colors are exponential with a lambda of about 2.2). Depending on your application, incorrectly assuming linearity might work OK anyway, especially if the starting colors are already close.
(As mentioned by luk2302, add a fourth coordinate for alpha if necessary).
You could use Java.awt.color by doing somting like this:
public Color mixColors(Color color1, Color color2, double percent){
double inverse_percent = 1.0 - percent;
int redPart = (int) (color1.getRed()*percent + color2.getRed()*inverse_percent);
int greenPart = (int) (color1.getGreen()*percent + color2.getGreen()*inverse_percent);
int bluePart = (int) (color1.getBlue()*percent + color2.getBlue()*inverse_percent);
return new Color(redPart, greenPart, bluePart);
}

Increasing luminous of a Color in android

I am using this code to randomly change the color of my textView. I have a black background so sometimes these colors are hard to read.
int r = (rand.nextInt(176) * 80 ) / 256;
int g = (rand.nextInt(176) * 80 ) / 256;
int b = (rand.nextInt(176) * 80 ) / 256;
TextView pos = (TextView) view.findViewById(R.id.position);
pos.setText(((Integer)(position + 1)).toString());
pos.setTextSize(30);
pos.setTextColor(Color.argb(255,r,g,b));
TextView data = (TextView) view.findViewById(R.id.textOfTip);
data.setText(tipsList[position].toString());
data.setTextSize(24);
data.setTextColor(Color.argb(255,r,g,b));
My question is, how can i increase the brightness or luminous effect of the text color so they can read easily.
Best Regards
First, get your color in the format 0xAARRGGBB (example, solid red is 0xFFFF0000). Then, push it to the method colorToHSV. Next, change the L/V/B value (which vary slightly, but I think will be close enough for what you're doing). Lastly, call HSVToColor to get your new color in 0xAARRGGBB format again. There are then several ways to convert this to R,G,B values, which usually involve byte shifting.
Something like this:
int color = 0xFFFF0000;
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] = 0.2f;
color = Color.HSVToColor(hsv);
int[] rgb = new int[3];
MyColor.colorToRGB(color, rgb); // Your custom method
// The rgb array now contains your RGB colors.
Note: There is also RGBToHSV, which may come in handy.
I think there are some formulae for acheiving the brightness and luminous effct.This article gives you good understanding about it.
Formula to determine brightness of RGB color

Color detector in Java

I have list of colors in HEX format (for example #000000) and I would like to detect color type (blue, red, green etc.) and then change color type to another color type. Is this possible and are there any frameworks/libraries for this task?
Example:
I have color #EB1369 (red) then I convert it to blue and it becomes for example #1313EB (blue).
Here's a function that will let you shift colors around the hue circle. You should read the wikipedia page on the HSB (or HSV) color system to really understand what is going on: http://en.wikipedia.org/wiki/HSV_color_space
/** Converts an input color given as a String such as "ab451e" to
* the HSB color space. Shifts its hue from the given angle in degrees.
* Then returns the new color in the same format it was given.
*
* For example shift("ff0000", 180); returns "80ff00" (green is the opposite of red).*/
public static String shift(String rgbS, int angle) {
// Convert String to integer value
int value = Integer.parseInt(rgbS, 16);
// Separate red green and blue
int r = value >> 16;
int g = (value >> 8) & 0xff;
int b = value & 0xff;
// Convert to hsb
float[] hsb = Color.RGBtoHSB(r, g, b, null);
// Convert angle to floating point between 0 and 1.0
float angleF = (float)(angle/360.0);
// Shift the hue using the angle.
float newAngle = hsb[0] + angleF;
if(newAngle > 1.0)
newAngle = newAngle - 1.0f;
hsb[0] = newAngle;
// Convert back to RGB, removing the alpha component
int rgb = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);
rgb = rgb & 0xffffff;
// Build a new String
return Integer.toHexString(rgb);
}
Detecting colors can be complex, it depends on the result you really expect.
If what you want is simply an approximation (red, green, blue, yellow, etc.) then you can look at the hue circle of the HSB color-space, choose a hue value for each color you want to define, and then map the color you get in input to the closest one you chose.
You can also rely on things like named HTML colors: http://www.w3schools.com/html/html_colornames.asp . Take this list, create a mapping in your program, then all you have to do is map the color you get to the closest one in your map, and return its name. Be wary though: computing the distance between two colors can be tricky (especially in RGB) and naive approaches (such as channel-by-channel difference) can give surprisingly bad results. Colorimetry is a complex topic, and you will find good methods on this page: http://en.wikipedia.org/wiki/Color_difference
Try convert RGB values to HSV (HSB exactly) - it is format for colors which is more comfortable for human. After conversion, all u need to do is change H V (probably) and convert it back to RGB.
I guess that you like to convert RGB color to HSB. YOu can do this wuth:
java.awt.Color.RGBtoHSB(...)
then you can easily determine whetther H value fits in your definition of blue, and modify it to whatever you like. After this, you can easily convert it back to RGB via:
java.awt.Color.getHSBColor(...)
And ifg you do not like jawa.awt.color just multiply color vector by transofrmation matrix.
Each HEX Color has three parts in it, red, green and blue the # identifies a HEX color, the following two letters are the amount of red; the next two are green and the next two are blue. i.e: RGB
The two letters can have a maximum hexidecimal value of FF which is 255, and a minimum of 00 which is zero.
So you can argue like this, I want a color with 2 red parts, 7 green parts, and zero blue parts, which will give you #020700
That is why #FFFFFF is white (all the colors together) and #000000 is black (no colors at all)
With this logic you can modify the color in any way you want; The Color class can also help a lot.

How to set unit for Paint.setTextSize()

Is it possible to change the unit for Paint.setTextSize()? As far as I know, it's pixel but I like to set the text size in DIP for multiple screen support.
I know this topic is old and already answered but I would like to also suggest this piece of code:
int MY_DIP_VALUE = 5; //5dp
int pixel= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
MY_DIP_VALUE, getResources().getDisplayMetrics());
Convert it like this
// The gesture threshold expressed in dip
private static final float GESTURE_THRESHOLD_DIP = 16.0f;
// Convert the dips to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);
// Use mGestureThreshold as a distance in pixels
from here http://developer.android.com/guide/practices/screens_support.html#dips-pels
The accepted answer is for gestures, not setting text size. The highest voted answer (at the time of this writing) is close, but the documentation recommends using sp rather than dp because in addition to being scaled for screen densities (as dp values are), sp is also scaled according to user preferred font sizes.
From an int in code
int spSize = 17;
float scaledSizeInPixels = spSize * getResources().getDisplayMetrics().scaledDensity;
mTextPaint.setTextSize(scaledSizeInPixels);
Or alternatively
int spSize = 17;
float scaledSizeInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
spSize, getResources().getDisplayMetrics());
mTextPaint.setTextSize(scaledSizeInPixels);
From resources
Or if you have the sp or dp value in resources:
<resources>
<dimen name="fontSize">17sp</dimen>
</resources>
with
float scaledSizeInPixels = getResources().getDimensionPixelSize(R.dimen.fontSize);
mTextPaint.setTextSize(scaledSizeInPixels);
Other links
How to convert DP, PX, SP among each other, especially DP and SP?
Android: Canvas.drawText() text size on different screen resolutions
Paint.setTextSize
getDimensionPixelSize
And here is even shorter method to convert dp-s to px-els taking display metrics into account
https://developer.android.com/reference/android/content/res/Resources.html#getDimensionPixelSize(int)
If your Paint object is being used to draw text on a Canvas, you can let the Canvas handle scaling for you.
When calling Canvas.drawText() the text size is first determined by the passed in Paint object, which can be set via Paint.setTextSize(). The text size is automatically scaled by Canvas based on the canvas density, which can be found using Canvas.getDensity().
When setting the text size on a paint object that will be drawn on Canvas, work with a unit value of dp or sp and let Canvas handle the scaling for you.

Categories

Resources