pantone online hexadecimal hexa google convertir convert colores color algorithm rgb

algorithm - online - Algoritmo para convertir cualquier entero positivo a un valor RGB



rgb to hex google (10)

Tenemos un mapa de calor que queremos mostrar. Los números que conformarán los valores que se muestran son desconocidos (excepto que serán enteros positivos). El rango de números también es desconocido (nuevamente, excepto que serán enteros positivos). El rango podría estar entre 0 y 200 o 578 y 1M o lo que sea. Depende de los datos, lo cual es desconocido.

Queremos tomar un rango desconocido de enteros positivos y convertirlo en un rango escalado (comprimido) para mostrarlo con valores RGB en un mapa de calor. Espero que esto tenga sentido. ¡Gracias!

Quiero aclarar que los valores mínimos / máximos deben estar "conectados" en el foro.


Algoritmo simple

// given a max and min value float red,green,blue; float range=max-min; float mid=(max+min)/2.0; //foreach value red = (value[ii]-mid)/range; if (red>0.0) { //above mid = red-green blue=0.0; green = 1.0-red; } else { // lower half green-blue blue=-red; green = 1.0-blue; red=0.0; } }

Mas complejo:
Si su rango es de unos pocos millones, pero la mayoría está alrededor de 0, debe escalarlo, de modo que ''rojo'' en el ejemplo anterior sea el registro de la distancia desde el punto medio. El bacalao es un poco más complicado si los valores son +/-

// assume equally distributed around 0 so max is the largest (or most negative number) float range = log(fabs(max)); float mid=0.0 // foreach value if (value[ii] > 0.0 ) { // above mid = red-green red = log(value[ii])/range; blue=0.0; green = 1.0 - red; } else { // below mid = green-blue blue=-log(value[ii])/range; green = 1.0 - blue; red = 0.0; }

nota - ¡No he probado este código, solo estoy girando ideas!


Continuando con la excelente respuesta de Ian Boyd, necesitaba un conjunto de colores distinguibles para construir un mapa de calor. El truco consistía en encontrar una manera de diferenciar los colores cercanos y encontré una solución al convertir HSV y variando la V según el valor, con un poco de énfasis en el centro de la gama de colores para resaltar los amarillos y naranjas.

Aquí está el código:

Imports System.Drawing Imports RGBHSV Module HeatToColour_ '' Thanks to Ian Boyd''s excellent post here: '' http://.com/questions/2374959/algorithm-to-convert-any-positive-integer-to-an-rgb-value Private Const MinVisibleWaveLength As Double = 450.0 Private Const MaxVisibleWaveLength As Double = 700.0 Private Const Gamma As Double = 0.8 Private Const IntensityMax As Integer = 255 Function HeatToColour(ByVal value As Double, ByVal MinValue As Double, ByVal MaxValues As Double) As System.Drawing.Color Dim wavelength As Double Dim Red As Double Dim Green As Double Dim Blue As Double Dim Factor As Double Dim scaled As Double scaled = (value - MinValue) / (MaxValues - MinValue) wavelength = scaled * (MaxVisibleWaveLength - MinVisibleWaveLength) + MinVisibleWaveLength Select Case Math.Floor(wavelength) Case 380 To 439 Red = -(wavelength - 440) / (440 - 380) Green = 0.0 Blue = 1.0 Case 440 To 489 Red = 0.0 Green = (wavelength - 440) / (490 - 440) Blue = 1.0 Case 490 To 509 Red = 0.0 Green = 1.0 Blue = -(wavelength - 510) / (510 - 490) Case 510 To 579 Red = (wavelength - 510) / (580 - 510) Green = 1.0 Blue = 0.0 Case 580 To 644 Red = 1.0 Green = -(wavelength - 645) / (645 - 580) Blue = 0.0 Case 645 To 780 Red = 1.0 Green = 0.0 Blue = 0.0 Case Else Red = 0.0 Green = 0.0 Blue = 0.0 End Select '' Let the intensity fall off near the vision limits Select Case Math.Floor(wavelength) Case 380 To 419 Factor = 0.3 + 0.7 * (wavelength - 380) / (420 - 380) Case 420 To 700 Factor = 1.0 Case 701 To 780 Factor = 0.3 + 0.7 * (780 - wavelength) / (780 - 700) Case Else Factor = 0.0 End Select Dim R As Integer = Adjust(Red, Factor) Dim G As Integer = Adjust(Green, Factor) Dim B As Integer = Adjust(Blue, Factor) Dim result As Color = System.Drawing.Color.FromArgb(255, R, G, B) Dim resulthsv As New HSV resulthsv = ColorToHSV(result) resulthsv.Value = 0.7 + 0.1 * scaled + 0.2 * Math.Sin(scaled * Math.PI) result = HSVToColour(resulthsv) Return result End Function Private Function Adjust(ByVal Colour As Double, ByVal Factor As Double) As Integer If Colour = 0 Then Return 0 Else Return Math.Round(IntensityMax * Math.Pow(Colour * Factor, Gamma)) End If End Function End Module Imports System.Drawing Public Module RGBHSV Public Class HSV Sub New() Hue = 0 Saturation = 0 Value = 0 End Sub Public Sub New(ByVal H As Double, ByVal S As Double, ByVal V As Double) Hue = H Saturation = S Value = V End Sub Public Hue As Double Public Saturation As Double Public Value As Double End Class Public Function ColorToHSV(ByVal color As Color) As HSV Dim max As Integer = Math.Max(color.R, Math.Max(color.G, color.B)) Dim min As Integer = Math.Min(color.R, Math.Min(color.G, color.B)) Dim result As New HSV With result .Hue = color.GetHue() .Saturation = If((max = 0), 0, 1.0 - (1.0 * min / max)) .Value = max / 255.0 End With Return result End Function Public Function HSVToColour(ByVal hsv As HSV) As Color Dim hi As Integer Dim f As Double With hsv hi = Convert.ToInt32(Math.Floor(.Hue / 60)) Mod 6 f = .Hue / 60 - Math.Floor(.Hue / 60) .Value = .Value * 255 Dim v As Integer = Convert.ToInt32(.Value) Dim p As Integer = Convert.ToInt32(.Value * (1 - .Saturation)) Dim q As Integer = Convert.ToInt32(.Value * (1 - f * .Saturation)) Dim t As Integer = Convert.ToInt32(.Value * (1 - (1 - f) * .Saturation)) If hi = 0 Then Return Color.FromArgb(255, v, t, p) ElseIf hi = 1 Then Return Color.FromArgb(255, q, v, p) ElseIf hi = 2 Then Return Color.FromArgb(255, p, v, t) ElseIf hi = 3 Then Return Color.FromArgb(255, p, q, v) ElseIf hi = 4 Then Return Color.FromArgb(255, t, p, v) Else Return Color.FromArgb(255, v, p, q) End If End With End Function End Module

y un mapa de calor resultante, que muestra el PIB per cápita de los países de la CEE:


Desea convertir sus valores de datos a una frecuencia de luz:

  • longitud de onda inferior = colores más fríos = azulado
  • mayor longitud de onda = colores más cálidos = más rojo

Las frecuencias de luz visible van desde aproximadamente 350nm (violeta) a 650nm (rojo):

texto alternativo http://www.gamonline.com/new/catalog/colortheory/images/spectrum.gif

La siguiente función convierte los números en su rango especificado al rango de luz visible, luego obtiene el rgb:

function DataPointToColor(Value, MinValue, MaxValue: Real): TColor; var r, g, b: Byte; WaveLength: Real; begin WaveLength := GetWaveLengthFromDataPoint(Value, MinValue, MaxValue); WavelengthToRGB(Wavelength, r, g, b); Result := RGB(r, g, b); end;

Con la función que escribí de la parte superior de mi cabeza:

function GetWaveLengthFromDataPoint(Value: Real; MinValues, MaxValues: Real): Real; const MinVisibleWaveLength = 350.0; MaxVisibleWaveLength = 650.0; begin //Convert data value in the range of MinValues..MaxValues to the //range 350..650 Result := (Value - MinValue) / (MaxValues-MinValues) * (MaxVisibleWavelength - MinVisibleWavelength) + MinVisibleWaveLength; end;

Y una función que encontré en las redes internas , que convierte una longitud de onda en RGB:

PROCEDURE WavelengthToRGB(CONST Wavelength: Nanometers; VAR R,G,B: BYTE); CONST Gamma = 0.80; IntensityMax = 255; VAR Blue : DOUBLE; factor : DOUBLE; Green : DOUBLE; Red : DOUBLE; FUNCTION Adjust(CONST Color, Factor: DOUBLE): INTEGER; BEGIN IF Color = 0.0 THEN RESULT := 0 // Don''t want 0^x = 1 for x <> 0 ELSE RESULT := ROUND(IntensityMax * Power(Color * Factor, Gamma)) END {Adjust}; BEGIN CASE TRUNC(Wavelength) OF 380..439: BEGIN Red := -(Wavelength - 440) / (440 - 380); Green := 0.0; Blue := 1.0 END; 440..489: BEGIN Red := 0.0; Green := (Wavelength - 440) / (490 - 440); Blue := 1.0 END; 490..509: BEGIN Red := 0.0; Green := 1.0; Blue := -(Wavelength - 510) / (510 - 490) END; 510..579: BEGIN Red := (Wavelength - 510) / (580 - 510); Green := 1.0; Blue := 0.0 END; 580..644: BEGIN Red := 1.0; Green := -(Wavelength - 645) / (645 - 580); Blue := 0.0 END; 645..780: BEGIN Red := 1.0; Green := 0.0; Blue := 0.0 END; ELSE Red := 0.0; Green := 0.0; Blue := 0.0 END; // Let the intensity fall off near the vision limits CASE TRUNC(Wavelength) OF 380..419: factor := 0.3 + 0.7*(Wavelength - 380) / (420 - 380); 420..700: factor := 1.0; 701..780: factor := 0.3 + 0.7*(780 - Wavelength) / (780 - 700) ELSE factor := 0.0 END; R := Adjust(Red, Factor); G := Adjust(Green, Factor); B := Adjust(Blue, Factor) END {WavelengthToRGB};

Uso de la muestra:

Datos establecidos en el rango de 10..65,000,000. Y este punto de datos en particular tiene un valor de 638,328:

color = DataPointToColor(638328, 10, 65000000);


Esta respuesta es probablemente un poco tarde para la fiesta. Estoy mostrando algunos datos ambientales, y necesito colorear las barras resultantes de verde a rojo en relación con el máximo y mínimo del conjunto de datos (o los valores que se hayan pasado como máximo y mínimo a la función. De todos modos, lo que sigue a continuación logra que Podría ser cambiado de azul a rojo con bastante facilidad, pensaría yo.

// scale colour temp relatively function getColourTemp(maxVal, minVal, actual) { var midVal = (maxVal - minVal)/2; var intR; var intG; var intB = Math.round(0); if (actual >= midVal){ intR = 255; intG = Math.round(255 * ((maxVal - actual) / (maxVal - midVal))); } else{ intG = 255; intR = Math.round(255 * ((actual - minVal) / (midVal - minVal))); } return to_rgb(intR, intG, intB); }


Función para barra de colores

// value between 0 and 1 (percent) function color(value) { var RGB = {R:0,G:0,B:0}; // y = mx + b // m = 4 // x = value // y = RGB._ if (0 <= value && value <= 1/8) { RGB.R = 0; RGB.G = 0; RGB.B = 4*value + .5; // .5 - 1 // b = 1/2 } else if (1/8 < value && value <= 3/8) { RGB.R = 0; RGB.G = 4*value - .5; // 0 - 1 // b = - 1/2 RGB.B = 1; // small fix } else if (3/8 < value && value <= 5/8) { RGB.R = 4*value - 1.5; // 0 - 1 // b = - 3/2 RGB.G = 1; RGB.B = -4*value + 2.5; // 1 - 0 // b = 5/2 } else if (5/8 < value && value <= 7/8) { RGB.R = 1; RGB.G = -4*value + 3.5; // 1 - 0 // b = 7/2 RGB.B = 0; } else if (7/8 < value && value <= 1) { RGB.R = -4*value + 4.5; // 1 - .5 // b = 9/2 RGB.G = 0; RGB.B = 0; } else { // should never happen - value > 1 RGB.R = .5; RGB.G = 0; RGB.B = 0; } // scale for hex conversion RGB.R *= 15; RGB.G *= 15; RGB.B *= 15; return Math.round(RGB.R).toString(16)+''''+Math.round(RGB.G).toString(16)+''''+Math.round(RGB.B).toString(16); }


Hombre, probablemente podrías usar el espacio de color YUV y solo para fines de demostración convertirlo a RGB.


Primero debes encontrar el rango de esos valores para obtener los valores mínimo y máximo. Entonces necesitas crear una escala de color como la barra debajo de esta imagen. Puede experimentar con diferentes funciones para asignar un número entero a un RGB. Necesita 3 funciones R (X), G (X), B (X). Al mirar la imagen debajo, se ve como picos B (X) en el medio, picos R (X) al final y verde en otra parte. Siempre que se asegure de que nunca obtenga dos (RGB) por algún valor de X, entonces obtendrá su conversión.

texto alt http://www.globalwarmingart.com/images/a/aa/Annual_Average_Temperature_Map.jpg

EDITAR: Piénsalo, puedes muestrear un círculo unitario alrededor del espacio YUV. texto alt http://www.biocrawler.com/w/images/e/ec/Yuv.png

O incluso simplemente descargue una barra de color de alta resolución y muestre eso.

EDIT 2: Me enfrenté a la generación de barras de colores y recordé el código de la barra de colores MATLAB / Octave. Traje sus datos y obtuve la siguiente imagen.


Saliendo de la imagen provista por Chris H, puede modelar los valores rgb como:

r = min(max(0, 1.5-abs(1-4*(val-0.5))),1); g = min(max(0, 1.5-abs(1-4*(val-0.25))),1); b = min(max(0, 1.5-abs(1-4*val)),1);


Sin conocer el rango de valores, no hay mucho que pueda hacer para encontrar una función significativa que asigne un rango arbitrario de enteros positivos a un rango de colores de tipo mapa de calor.

Creo que tendrá que revisar sus datos al menos una vez para obtener el mínimo / máximo o conocerlos antes de tiempo. Una vez que tenga eso, puede normalizarse adecuadamente y usar cualquier número de combinaciones de colores. La solución más simple sería especificar algo como "tono" y convertir de HSV a RGB.


Un poco tarde, pero estaba tratando de hacer lo mismo y descubrí que puedo modificar HSV a RGB para obtener un resultado similar. Es similar al enfoque de la longitud de onda, pero al pasar la necesidad de convertir primero a la longitud de onda. Simplemente sustituya H con su valor (asumiendo un valor entre 0 y 1), y corrija S y V a 1. Encontré que el ejemplo de HSVtoRGB es muy útil:

http://www.cs.rit.edu/~ncs/color/t_convert.html

Sin embargo, tuve que cambiar las líneas.

h /= 60; i = floor ( h );

a

h *= 5; i = (int) h;

Para obtener una salida que atraviesa todo el espectro.

Recurso adicional: http://www.easyrgb.com/index.php?X=MATH&H=21#text21