Fortran 如何将颜色波长转换为RGB或HSL?
我正在做一个项目,其中一部分需要从颜色波长转换为RGB/HSL/HSV(任何一种),所以我找到了这个页面:我有点理解它,但我需要它作为Javascript函数 我试着在色调值和波长之间做一个简单的比例,但感觉不对。我发现的代码是用Fortran编写的: Dan Bruton的可见波长RGB值(astro@tamu.edu) 此程序可在以下网址找到: 最后更新日期为1996年2月20日。 该程序将创建频谱的ppm(便携式pixmap)图像。 光谱是使用可见光的近似RGB值生成的 波长在380纳米到780纳米之间。 NetPBM的ppmtogif可用于转换ppm图像 到gif。红色、绿色和蓝色值(RGB)为 假设随波长线性变化(对于GAMMA=1)。Fortran 如何将颜色波长转换为RGB或HSL?,fortran,Fortran,我正在做一个项目,其中一部分需要从颜色波长转换为RGB/HSL/HSV(任何一种),所以我找到了这个页面:我有点理解它,但我需要它作为Javascript函数 我试着在色调值和波长之间做一个简单的比例,但感觉不对。我发现的代码是用Fortran编写的: Dan Bruton的可见波长RGB值(astro@tamu.edu) 此程序可在以下网址找到: 最后更新日期为1996年2月20日。 该程序将创建频谱的ppm(便携式pixmap)图像。 光谱是使用可见光的近似RGB值生成的 波长在380纳米到
NetPBM软件: 图像信息-宽度、高度、深度、伽马
M=400
N=50
MAX=255
GAMMA=.80
将输出写入PPM文件
OPEN(UNIT=20,FILE='temp.ppm',STATUS='UNKNOWN')
FORMAT(A10)
WRITE(20,1) 'P3 '
WRITE(20,1) '# temp.ppm'
WRITE(20,*) M,N
WRITE(20,*) MAX
DO J=1,N
DO I=1,M
WAVELENGTH = WL
WL = 380. + REAL(I * 400. / M)
IF ((WL.GE.380.).AND.(WL.LE.440.)) THEN
R = -1.*(WL-440.)/(440.-380.)
G = 0.
B = 1.
ENDIF
IF ((WL.GE.440.).AND.(WL.LE.490.)) THEN
R = 0.
G = (WL-440.)/(490.-440.)
B = 1.
ENDIF
IF ((WL.GE.490.).AND.(WL.LE.510.)) THEN
R = 0.
G = 1.
B = -1.*(WL-510.)/(510.-490.)
ENDIF
IF ((WL.GE.510.).AND.(WL.LE.580.)) THEN
R = (WL-510.)/(580.-510.)
G = 1.
B = 0.
ENDIF
IF ((WL.GE.580.).AND.(WL.LE.645.)) THEN
R = 1.
G = -1.*(WL-645.)/(645.-580.)
B = 0.
ENDIF
IF ((WL.GE.645.).AND.(WL.LE.780.)) THEN
R = 1.
G = 0.
B = 0.
ENDIF
DO J=1,N
DO I=1,M
WL = 380. + REAL(I * 400. / M)
IR=INT(MAX*CV(I,J,1))
IG=INT(MAX*CV(I,J,2))
IB=INT(MAX*CV(I,J,3))
ITYPE=1 - PLAIN SPECTUM
ITYPE=2 - MARK SPECTRUM AT 100 nm INTEVALS
ITYPE=3 - HYDROGEN BALMER EMISSION SPECTRA
ITYPE=4 - HYDROGEN BALMER ABSORPTION SPECTRA
ITYPE=4
IF (ITYPE.EQ.2) THEN
DO K=400,700,100
IF ((ABS(INT(WL)-K).LT.1).AND.(J.LE.20)) THEN
IR=MAX
IG=MAX
IB=MAX
ENDIF
ENDDO
ELSEIF (ITYPE.EQ.3) THEN
IF ((ABS(WL-656.).GT.1.).and.(ABS(WL-486.).GT.1.).and.
* (ABS(WL-433.).GT.1.).and.(ABS(WL-410.).GT.1.)
* .AND.(ABS(WL-396.).GT.1.)) THEN
IR = 0
IG = 0
IB = 0
ENDIF
ELSEIF (ITYPE.EQ.4) THEN
IF ((ABS(WL-656.).LT.1.1).or.(ABS(WL-486.).LT.1.1).or.
* (ABS(WL-433.).LT.1.1).or.(ABS(WL-410.).LT.1.1)
* .or.(ABS(WL-396.).LT.1.1)) THEN
IR = 0
IG = 0
IB = 0
ENDIF
ENDIF
WRITE(20,*) IR, IG, IB
ENDDO
ENDDO
STOP
END
让强度SSS在视觉极限附近下降
IF (WL.GT.700.) THEN
SSS=.3+.7* (780.-WL)/(780.-700.)
ELSE IF (WL.LT.420.) THEN
SSS=.3+.7*(WL-380.)/(420.-380.)
ELSE
SSS=1.
ENDIF
GAMMA调整并将图像写入阵列
CV(I,J,1)=(SSS*R)**GAMMA
CV(I,J,2)=(SSS*G)**GAMMA
CV(I,J,3)=(SSS*B)**GAMMA
ENDDO
ENDDO
将图像写入PPM文件
OPEN(UNIT=20,FILE='temp.ppm',STATUS='UNKNOWN')
FORMAT(A10)
WRITE(20,1) 'P3 '
WRITE(20,1) '# temp.ppm'
WRITE(20,*) M,N
WRITE(20,*) MAX
DO J=1,N
DO I=1,M
WAVELENGTH = WL
WL = 380. + REAL(I * 400. / M)
IF ((WL.GE.380.).AND.(WL.LE.440.)) THEN
R = -1.*(WL-440.)/(440.-380.)
G = 0.
B = 1.
ENDIF
IF ((WL.GE.440.).AND.(WL.LE.490.)) THEN
R = 0.
G = (WL-440.)/(490.-440.)
B = 1.
ENDIF
IF ((WL.GE.490.).AND.(WL.LE.510.)) THEN
R = 0.
G = 1.
B = -1.*(WL-510.)/(510.-490.)
ENDIF
IF ((WL.GE.510.).AND.(WL.LE.580.)) THEN
R = (WL-510.)/(580.-510.)
G = 1.
B = 0.
ENDIF
IF ((WL.GE.580.).AND.(WL.LE.645.)) THEN
R = 1.
G = -1.*(WL-645.)/(645.-580.)
B = 0.
ENDIF
IF ((WL.GE.645.).AND.(WL.LE.780.)) THEN
R = 1.
G = 0.
B = 0.
ENDIF
DO J=1,N
DO I=1,M
WL = 380. + REAL(I * 400. / M)
IR=INT(MAX*CV(I,J,1))
IG=INT(MAX*CV(I,J,2))
IB=INT(MAX*CV(I,J,3))
ITYPE=1 - PLAIN SPECTUM
ITYPE=2 - MARK SPECTRUM AT 100 nm INTEVALS
ITYPE=3 - HYDROGEN BALMER EMISSION SPECTRA
ITYPE=4 - HYDROGEN BALMER ABSORPTION SPECTRA
ITYPE=4
IF (ITYPE.EQ.2) THEN
DO K=400,700,100
IF ((ABS(INT(WL)-K).LT.1).AND.(J.LE.20)) THEN
IR=MAX
IG=MAX
IB=MAX
ENDIF
ENDDO
ELSEIF (ITYPE.EQ.3) THEN
IF ((ABS(WL-656.).GT.1.).and.(ABS(WL-486.).GT.1.).and.
* (ABS(WL-433.).GT.1.).and.(ABS(WL-410.).GT.1.)
* .AND.(ABS(WL-396.).GT.1.)) THEN
IR = 0
IG = 0
IB = 0
ENDIF
ELSEIF (ITYPE.EQ.4) THEN
IF ((ABS(WL-656.).LT.1.1).or.(ABS(WL-486.).LT.1.1).or.
* (ABS(WL-433.).LT.1.1).or.(ABS(WL-410.).LT.1.1)
* .or.(ABS(WL-396.).LT.1.1)) THEN
IR = 0
IG = 0
IB = 0
ENDIF
ENDIF
WRITE(20,*) IR, IG, IB
ENDDO
ENDDO
STOP
END
嗯,我甚至从未听说过Fortran代码,所以我不知道它是如何工作的。有人能帮我吗?如果您知道这一点,代码很容易阅读
.GT. = greater than
.GE. = greater than or equal to
.LT. = less than
.LE. = less than or equal to
1. = 1.000
1.1 = 1.1000
.1 = 0.1000
1.1.GT.1
与1.1>1
相同。进一步
!this is a comment
IMPLICIT REAL*8 (a-h,o-z) !variables starting with a,b,...h and o,..,z are double scalars
REAL*8 CV(500,500,3) ! this is an array of doubles
现在编写JavaScript 为了避免将来的麻烦,下面是转换为javascript的fortran代码:
const wl2rgb_pregamma = wl => {
if (wl >= 380 && wl < 440) {
const s = wl < 420 ? 0.3 + (0.7 * (wl - 380.0)) / (420.0 - 380.0) : 1.0;
return [(s * -1 * (wl - 440)) / (440 - 380), 0, s];
}
if (wl >= 440 && wl < 490) {
return [0, (wl - 440) / (490 - 440), 1];
}
if (wl >= 490 && wl < 510) {
return [0, 1, (-1 * (wl - 510)) / (510 - 490)];
}
if (wl >= 510 && wl < 580) {
return [(wl - 510) / (580 - 510), 1.0, 0.0];
}
if (wl >= 580 && wl < 645) {
return [1, (-1 * (wl - 645)) / (645 - 580), 0];
}
if (wl > 700) {
return [0.3 + (0.7 * (780 - wl)) / (780 - 700), 0, 0];
}
return [1, 0, 0];
};
const wl2rgb = wl => {
const gamma = 0.8;
const [r, g, b] = wl2rgb_pregamma(wl);
return [Math.pow(r, gamma), Math.pow(g, gamma), Math.pow(b, gamma)];
};
const wl2rgb\u pregamma=wl=>{
如果(wl>=380&&wl<440){
常数s=wl<420?0.3+(0.7*(wl-380.0))/(420.0-380.0):1.0;
返回[(s*-1*(wl-440))/(440-380),0,s];
}
如果(wl>=440&&wl<490){
返回[0,(wl-440)/(490-440),1];
}
如果(wl>=490&&wl<510){
返回[0,1,(-1*(wl-510))/(510-490)];
}
如果(wl>=510&&wl<580){
回报率[(wl-510)/(580-510),1.0,0.0];
}
如果(wl>=580&&wl<645){
返回[1,(-1*(wl-645))/(645-580),0];
}
如果(wl>700){
返回[0.3+(0.7*(780-wl))/(780-700),0,0];
}
返回[1,0,0];
};
常量wl2rgb=wl=>{
常数伽马=0.8;
常数[r,g,b]=wl2rgb_pregamma(wl);
return[Math.pow(r,gamma),Math.pow(g,gamma),Math.pow(b,gamma)];
};
要在画布上试用:
var ctx = canvas.getContext("2d");
for (var i = 380; i < 780; i++) {
const [r,g,b] = wl2rgb(i);
ctx.fillStyle = `rgb(${r*255}, ${g*255}, ${b*255})`;
ctx.fillRect(i - 380, 0, 1, 50);
}
var ctx=canvas.getContext(“2d”);
对于(变量i=380;i<780;i++){
常数[r,g,b]=wl2rgb(i);
ctx.fillStyle=`rgb(${r*255},${g*255},${b*255})`;
ctx.fillRect(i-380,0,1,50);
}
波长只能转换为色调。公式与图形 公式是(如果w=波长,h=色调):h=(40/27)w或w=(27h)/40。
该图位于(色调为x,波长(nm)为y)。
请注意,如果波长小于400或大于650,则可能需要向色调添加360,直到波长大于400或小于650 代码 色调与波长
h=输入('Hue:');
def hw():
w=27*int(h);
w/=40;
当w>650或w<400时:
hw()
印刷品(w);
##色相波长##
w=输入('波长单位为nm:')
h=40/27
h*=w
也许本文档将帮助您实现它。这与javascript有什么关系?@Justinas哦,我忘了提到我需要在javascript上使用它……无论如何,谢谢。。。