/*
* JEF - Copyright 2009-2010 Jiyi (mr.jiyi@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jef.common;
import java.awt.Color;
import java.util.Random;
import jef.tools.Assert;
import jef.tools.StringUtils;
/**
* 用于描述RGB色彩空间的一个颜色
* @author Administrator
*/
public class RGB {
public int red;
public int green;
public int blue;
public RGB() {
};
public RGB(int r, int g, int b) {
this.red = r;
this.green = g;
this.blue = b;
}
public int getBlue() {
return blue;
}
public int getGreen() {
return green;
}
public int getRed() {
return red;
}
public void setData(int[] data) {
Assert.equals(data.length, 3, "A array to describe cloor must be length=3");
red = data[0];
green = data[1];
blue = data[2];
}
public static RGB getInstance(Color color) {
return getInstance(color.getRGB());
}
public static RGB getInstance(int[] data) {
RGB rgb = new RGB();
rgb.setData(data);
return rgb;
}
public static RGB getInstance(int data) {
RGB rgb = new RGB();
rgb.blue = (data & 0xff);
rgb.green = (data >> 8 & 0xff);
rgb.red = (data >> 16 & 0xff);
return rgb;
}
public int[] getData() {
return new int[] { red, green, blue };
}
public String toString() {
return StringUtils.join(getData(), ",");
}
public int distanceGray() {
int min = Math.min(Math.min(red, green), blue);
int ro = red - min;
int go = green - min;
int bo = blue - min;
return Math.max(Math.max(ro, go), bo);
}
/**
* yuv色彩模型来源于rgb模型, 该模型的特点是将亮度和色度分离开,从而适合于图像处理领域。 basic color model used in
* analogue color TV broadcasting.
*
* @return
*/
public static RGB fromYUV(float[] yuv) {
RGB rgb = new RGB();
rgb.red = (int) (yuv[0] + 1.14 * yuv[2] + .5f);
rgb.green = (int) (yuv[0] - 0.39 * yuv[1] - 0.58 * yuv[2] + .5f);
rgb.blue = (int) (yuv[0] + 2.03 * yuv[1] + .5f);
return rgb;
}
/**
* 转换到YUV空间
*
* @return
*/
public float[] toYUV() {
float yuv[] = new float[3];
yuv[0] = (0.299f * red + 0.587f * green + 0.114f * blue);
yuv[1] = (-0.147f * red - 0.289f * green + 0.436f * blue);
yuv[2] = (0.615f * red - 0.515f * green - 0.100f * blue);
return yuv;
}
/**
* YCbCr模型来源于yuv模型。YCbCr is a scaled and offset version of the YUV color
* space. 应用:数字视频
*
* @return
*/
public float[] toYCrCb() {
float yuv[] = new float[3];
yuv[0] = 0.299f * red + 0.587f * green + 0.114f * blue;
yuv[1] = 0.5f * red - 0.4187f * green - 0.0813f * blue + 128;
yuv[2] = -0.1687f * red - 0.3313f * green + 0.5f * blue + 128;
return yuv;
}
/**
* 转换到YCrCb空间
*
* @param yCrCb
* @return
*/
public static RGB fromYCrCb(float[] yCrCb) {
int R = (int) (yCrCb[0] + 1.402 * (yCrCb[1] - 128) + .5f);
int G = (int) (yCrCb[0] - (0.34414 * (yCrCb[2] - 128)) - (0.71414 * (yCrCb[1] - 128)) + .5f);
int B = (int) (yCrCb[0] + (1.772 * (yCrCb[2] - 128)) + .5f);
return new RGB(R, G, B);
}
/**
* 从HSB空间转回
*/
public static RGB fromHSB(float[] fs) {
return RGB.getInstance(Color.HSBtoRGB(fs[0], fs[1], fs[2]));
}
/**
* 转换到HSB空间(圆锥空间) 返回:弧度、0~1,0~1比例。
* 一个参数用弧度表示在锥形地面上的角度——即色相(红色为0度,Green是120度,Blue在240度,对应为弧度red=0,green=2/3*PI,Blue是4/3*PI)
*
*
*/
public float[] toHSB() {
float[] hsb = Color.RGBtoHSB(red, green, blue, null);
return hsb;
}
/**
* 转换到HSL空间(圆锥空间) 返回:0~1,0~1,0~1比例
*
*
* HSL即色相、饱和度、亮度(英语:Hue, Saturation, Lightness),又称HLS。HSV即色相、饱和度、明度(英语:Hue, Saturation, Value),又称HSB,其中B即英语:Brightness。
*/
public float[] toHSL() {
float H, S, L, var_Min, var_Max, del_Max, del_R, del_G, del_B;
H = 0;
var_Min = Math.min(red, Math.min(blue, green));
var_Max = Math.max(red, Math.max(blue, green));
del_Max = var_Max - var_Min;
L = (var_Max + var_Min) / 2;
if (del_Max == 0) {// 灰度色
H = 0;
S = 0;
} else {
if (L < 128) {
S = 255 * del_Max / (var_Max + var_Min);
} else {
S = 255 * del_Max / (512 - var_Max - var_Min);
}
del_R = ((360 * (var_Max - red) / 6) + (360 * del_Max / 2)) / del_Max;
del_G = ((360 * (var_Max - green) / 6) + (360 * del_Max / 2)) / del_Max;
del_B = ((360 * (var_Max - blue) / 6) + (360 * del_Max / 2)) / del_Max;
if (red == var_Max) {
H = del_B - del_G;
} else if (green == var_Max) {
H = 120 + del_R - del_B;
} else if (blue == var_Max) {
H = 240 + del_G - del_R;
}
if (H < 0)
H += 360;
if (H >= 360)
H -= 360;
}
return new float[] { H / 360, S / 255, L / 255 };
}
/**
* 从HSL空间转换
*/
public static RGB fromHSL(float[] hsl) {
if (hsl == null) {
return null;
}
float H = hsl[0] * 360;
float S = hsl[1] * 255;
float L = hsl[2] * 255;
float R, G, B, var_1, var_2;
if (S == 0) {
R = L;
G = L;
B = L;
} else {
if (L < 128) {
var_2 = (L * (256 + S)) / 256;
} else {
var_2 = (L + S) - (S * L) / 256;
}
if (var_2 > 255) {
var_2 = Math.round(var_2);
}
if (var_2 > 254) {
var_2 = 255;
}
var_1 = 2 * L - var_2;
R = RGBFromHue(var_1, var_2, H + 120);
G = RGBFromHue(var_1, var_2, H);
B = RGBFromHue(var_1, var_2, H - 120);
}
R = R < 0 ? 0 : R;
R = R > 255 ? 255 : R;
G = G < 0 ? 0 : G;
G = G > 255 ? 255 : G;
B = B < 0 ? 0 : B;
B = B > 255 ? 255 : B;
return new RGB((int) Math.round(R), (int) Math.round(G), (int) Math.round(B));
}
public static float RGBFromHue(float a, float b, float h) {
if (h < 0) {
h += 360;
}
if (h >= 360) {
h -= 360;
}
if (h < 60) {
return a + ((b - a) * h) / 60;
}
if (h < 180) {
return b;
}
if (h < 240) {
return a + ((b - a) * (240 - h)) / 60;
}
return a;
}
/**
* 指定在角度和长度上的缩放比例后返回HSL颜色值
* Photoshop中的HSL就是 toHSL(360,100)
* Windows绘图中的HSL就是 toHSL(240,240)
* @param i
* @param j
* @return
*/
public int[] toHSL(int i, int j) {
float[] hsl = toHSL();
int[] data = new int[3];
data[0] = (int) (hsl[0] * i + 0.5f);
data[1] = (int) (hsl[1] * j + 0.5f);
data[2] = (int) (hsl[2] * j + 0.5f);
return data;
}
/**
* 指定在角度和长度上的缩放比例后返回HSB颜色值(某些绘图软件中称为HSV)<br>
* HSL和HSB(HSV)都是锥形色彩空间,因此其
*
* Photoshop中的HSV就是 toHSB(360,100)
* Windows绘图中的HSV就是 toHSB(240,240)
* @param i
* @param j
* @return
*/
public int[] toHSB(int i, int j) {
float[] hsb = toHSB();
int[] data = new int[3];
data[0] = (int) (hsb[0] * i + 0.5f);
data[1] = (int) (hsb[1] * j + 0.5f);
data[2] = (int) (hsb[2] * j + 0.5f);
return data;
}
/**
* 转换为java的Color对象
* @return
*/
public Color toColor(){
return new Color(red,green,blue);
}
/**
* 产生一个随机颜色
* @return
*/
public static RGB randomColor() {
Random r=new Random();
int a=((int)r.nextInt(52))*5;
int b=((int)r.nextInt(52))*5;
int c=((int)r.nextInt(52))*5;
return new RGB(a,b,c);
}
}