001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019/** 020 * A class for calulating the colors of the spectrum. 021 */ 022public class Spectrum { 023 024 private static int adjust(float color, float factor, float gamma) { 025 if (color == 0.0) 026 return 0; 027 return (int)Math.round(255 * Math.pow(color * factor, gamma)); 028 } 029 030 /** 031 * Convert a wavelength to an RGB value. 032 * @param wavelength wavelength in nanometres 033 * @return the RGB value 034 */ 035 public static int wavelengthToRGB(float wavelength) { 036 float gamma = 0.80f; 037 float r, g, b, factor; 038 039 int w = (int)wavelength; 040 if (w < 380) { 041 r = 0.0f; 042 g = 0.0f; 043 b = 0.0f; 044 } else if (w < 440) { 045 r = -(wavelength - 440) / (440 - 380); 046 g = 0.0f; 047 b = 1.0f; 048 } else if (w < 490) { 049 r = 0.0f; 050 g = (wavelength - 440) / (490 - 440); 051 b = 1.0f; 052 } else if (w < 510) { 053 r = 0.0f; 054 g = 1.0f; 055 b = -(wavelength - 510) / (510 - 490); 056 } else if (w < 580) { 057 r = (wavelength - 510) / (580 - 510); 058 g = 1.0f; 059 b = 0.0f; 060 } else if (w < 645) { 061 r = 1.0f; 062 g = -(wavelength - 645) / (645 - 580); 063 b = 0.0f; 064 } else if (w <= 780) { 065 r = 1.0f; 066 g = 0.0f; 067 b = 0.0f; 068 } else { 069 r = 0.0f; 070 g = 0.0f; 071 b = 0.0f; 072 } 073 074 // Let the intensity fall off near the vision limits 075 if (380 <= w && w <= 419) 076 factor = 0.3f + 0.7f*(wavelength - 380) / (420 - 380); 077 else if (420 <= w && w <= 700) 078 factor = 1.0f; 079 else if (701 <= w && w <= 780) 080 factor = 0.3f + 0.7f*(780 - wavelength) / (780 - 700); 081 else 082 factor = 0.0f; 083 084 int ir = adjust(r, factor, gamma); 085 int ig = adjust(g, factor, gamma); 086 int ib = adjust(b, factor, gamma); 087 088 return 0xff000000 | (ir << 16) | (ig << 8) | ib; 089 } 090 091}