HSB矩形调色板设计和计算方法
RGB调色板绘制较容易,HSB调色板较难绘制,前些天发文介绍了几个矩形样例的绘制方法,今介绍矩形的HSB调色板的设计方法和H,S,B值的计算方法,好东西必须与大家分享。
此文介绍HSB调色板和选色条的绘制方法,依据此方法可以仿制那些大牌绘图软件的调色板,在自己编制应用程序时遇到需要选色时,就要有调色板来选色,此方法就能使你很方便地创制自己的调色板。
SB选色条有二类:
一是双条式:S条饱和度从左起为100,向右趋向于0,即从原色到白色。B条亮度从右起为100,向左趋向于0,即从原色到黑色。B条也可设置为左起。
二是单条式:SB条合二为一,中间是它们的起始值100。S饱和度从中间100向右趋向于0,即从原色到白色。B亮度从中间100向左趋向于0,即从原色到黑色。此例采用双条式。
H调色板取色,二种设置,一是只取水平方向的值,0-360来计算H的色值。二是上下方向也取色,中线往上是S值,往下是V值。取色操作较麻烦。我采用分开取色,H板只取值计算H值,另加SV取色条,分别设置选色计算SV值。这样操作较方便。
SV取色条还有种取色方法,即用getpixel()方法,此方法简单直接,所见即所得。
HSB 矩形调色板设计要点:
1)界面设计,H 调色板绘制,SB 选色条绘制, colorpad8 () ;
2)H 调色板点击选色,Hselect (),计算 H值;
3)H 值更新,同步SB 选色条更新,HRenew ();
4)SB 选色条点击选色,SRenew (),VRenew ();
S, B值计算,值更新,显示更新。
源码中有详细注释,原理和语法都很简单,适用于初学者。希望大家喜欢。大家的点评是对我的鼓励。
补充一点,H板mouse或触控,若限定宽高,计算H是宽度,不会有越界问题。 SB选色条也这样。
RGB色 (+-)可设置调节rgb色彩,本例未设置。
以下是源码:
//OK按钮和H板,S,V取色条设置
//H色板mousemove, click选色,
{ px=x; py=y; //可设置为mousemove
Hselect () ; } //H 色板click选色
// S选色框mousemove, click > 改变颜色
{ x1=x ;
SRenew (); }
// V选色框mousemove, click > 改变颜色
{ x2=x ;
VRenew (); }
cmdOK_click ( ){
// OK按钮, click 新的颜色选用 > 应用
cs.SetFillMode (1) ;
cs.SetColor (255, r1, g1, b1) ;
cs.DrawRect (100,625,220,680); //新的选色
cs.SetTextSize (24);
cs.SetColor (255,0,250,0 ) ;
cs.DrawText ("应用颜色:", 100,610) ;
}
//界面设计:
colorpad8 (){ //HSV 调色板设计示例(8)
//本例以windows窗体图片来示例。其实在Windows中用绘画语句也能画出窗体,我喜欢自己设计绘制各种图形图样,绘制按钮,滚动条等,甚至开个无框窗体,自己在Form上绘制个人风格的自制窗体,加个图片框设置应用功能。
cs.ClearDraw (0,src);
fname="/storage/emulated/0/form.jpg";
cs.DrawBitmap(fname,0,6); //加底图
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,0,0,0);
cs.DrawRect (0,2,720,22);
cs.DrawRect (0,2,12,570);
cs.DrawRect (0,570,720,700);
cs.SetColor (255,100,100,100);
cs.DrawRect (28,65,709,521); //大框线
//绘制调色板( HSV )
cs.SetStrokeWidth(1); //线宽
//red-yellow-green-cyan-blue-purple-magenta-red
for (i=0;i<=255;i++){ //绘制 H 调色板
cs.SetColor (255,255,i,0); //red-yellow
cs.DrawLine (i/3+50,80,i/3+50,280);
cs.SetColor (255,255-i,255,0); //yellow-green
cs.DrawLine (i/3+135,80,i/3+135,280);
cs.SetColor (255,0,255,i); //green-blue
cs.DrawLine (i/3+220,80,i/3+220,280);
cs.SetColor (255,0,255-i,255); //blue-purple
cs.DrawLine (i/3+305,80,i/3+305,280);
cs.SetColor (255,i, 0,255); //purple-magenta
cs.DrawLine (i/3+390,80,i/3+390,280);
cs.SetColor (255,255,0,255-i); //magenta-red
cs.DrawLine (i/3+475,80,i/3+475,280); }
//画上高光和下暗部 HSB set brightness
cs.SetFillMode (0) ;
cs.SetStrokeWidth(2); //线宽
for (i= 0; i<=100 ; i++ ){ //高光
ca=255-i*3 ;
if (ca<0) ca=0 ;
cs.SetColor(ca,255,255,255 );
cs.DrawRect (50,80, 560,80+i ) ; }
cs.SetStrokeWidth(1); //线宽
for (i= 0; i<=100 ; i++ ){ //暗部
ca=255-i*3 ;
if (ca<0) ca=0 ;
cs.SetColor(ca, 0, 0, 0 );
cs.DrawRect (51,280, 560,280-i ) ; }
//**** 计算HSV ********
//调色板尺寸: (50,80,560,280);
//mouse 调色板取色 xpos 计算, Hue 值0-360
//依取值计算 RGB 值,cr, cg, cb
//六段画调色板 255/3=85, 85*6=510 = 色板宽度
// 1. (255,255,i,0); //red-yellow 0 - 59
// 2. (255,255-i,255,0); //yellow-green 60 -119
// 3. (255,0,255,i); //green-blue 120-179
// 4. (255,0,255-i,255); //blue-purple 180-239
// 5. (255, i , 0,255); //purple-magenta 240-299
// 6. (255,255,0,255-i); //magenta-red 300-360
//依此6段设色,每段60度,可定RGB色
// 135, 85=60, 220, 170=120°, 305, 255=180° ,
// 390, 340=240 , 475, 425=300°, 560, 510=360°
//标xpos=px, H=(px-50)/1.4166
//依mouse 选色 > 计算H 值
//px=510/360=1.4166(每度)
px=H*1.416+50 ; //反求 px 画游标
//标记H值画游标,更新数值,更新选色块
cs.SetFillMode (1);//0不填色,1填色
cs.SetStrokeWidth(3);
cs.SetColor(255,110,110,110 );
cs.DrawRect (46,281,564,295); //擦除
cs.SetColor(255,255,0,0 );
cs.DrawRect (px-1,281,px+1,294); //游标
cs.DrawCircle (px,290,4) ;
cs.Update ();
//H色板显示mouse 选色,计算RGB (r,g,b)
cs.SetFillMode (1) ;
if (H<=60) { //1. red
cr=255; cb=0;
cg=(int)(H*255/60) ; }
if (H>60&&H<=120) { //2. yellow
cg=255; cb=0;
cr=(int)(255-(H-60)*255/60) ; }
if (H>120&&H<=180) { //3. green
cr=0; cg=255;
cb=(int)((H-120)*255/60) ; }
if (H>180&&H<=240) { //4. cyan
cg=(int)(255-(H-180)*255/60 ) ;
cr=0 ; cb=255 ; }
if (H>240&&H<=300) { //5. blue
cr=(int)((H-240)*255/60 ) ;
cg=0 ; cb=255 ; }
if (H>300&&H<=360) { //6. magenta
cr=255; cg=0;
cb=(int)(255-(H-300)*255/60 ) ; }
r1=cr ; g1=cg ; b1=cb ; //新的初值
//依选色值计算,显示取色
cs.SetFillMode (1) ;
cs.SetColor (255, cr, cg, cb );
cs.DrawRect (612,82,664,134); //H板色show
cs.DrawRect (469,305,550,398); //新的选色
//取色后,S和B 的初始值是100。即选色条右位
// S=100 ; V=100 ; //初始值
//选色条颜色依所取色来绘出,六类基色1-6
// S.xpos<435, V=100, V.xpos<435, S=100
//拖动游标改变取色
//计算S,V 值,联动SV值显示和已选色更新(新的)
//Windows编程,标尺设置很简单
//依H绘制选色条:draw SV select color bar
R=cr ; G=cg ; B=cb ;
cs.SetStrokeWidth(2);
for (i=0;i<=255 ;i++){ //调色板:选色条
R=R+i ; G=G+i ; B=B+i ;
if (R>255) R=255 ;
if (G>255) G=255 ;
if (B>255) B=255 ;
cs.SetColor (255, R, G, B ) ;
cs.DrawLine (435-i*1.5, 305,435-i*1.5,330);
R=R-i ; G=G-i ; B=B-i ;
if (R<0) R=0 ;
if (G<0) G=0 ;
if (B<0) B=0 ;
cs.SetColor (255, R, G, B ) ;
cs.DrawLine (435-i*1.5, 375,435-i*1.5, 400 ); }
//画S,B标尺标线
cs.SetStrokeWidth(1);
cs.SetTextStyle (0) ;
for (i=0; i<=10; i++){ //画标线
dx=i*25.5*1.5 ;
cs.SetColor (255, 250, 250, 250 ) ;
cs.DrawLine (dx+51,343,dx+51,348);
cs.DrawLine (dx+51,367,dx+51,372);
}
cs.SetFillMode (1) ;
cs.SetTextSize (16);
cs.DrawText ("0 ", 46,363);
cs.DrawText ("100 ", 418,363);
//画游标
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,250,20,250);
x1=435 ; x2=435 ; //S, V值初始值 100=435
cs.SetStrokeWidth(2);
cs.SetColor (255,250,0,0);
cs.DrawRect (x1-1,331,x1+1,337); //游标尺1
cs.DrawCircle (x1,337,4);
cs.DrawRect (x2-1,401,x2+1,407); //游标尺2
cs.DrawCircle (x2,407,4);
//显示HSB计算结果
cs.SetTextStyle (0) ;
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,150,150,150);
cs.DrawRect (610,147,665,180); //标值
cs.DrawRect (610,187,665,220);
cs.DrawRect (610,227,665,260);
cs.DrawRect (610,287,665,320);
cs.DrawRect (610,327,665,360);
cs.DrawRect (610,367,665,400);
cs.SetTextSize (20);
cs.SetColor (255,240,240,240);
cs.DrawText ("< H : ", 564,115);
cs.DrawText ("R : ", 580,170);
cs.DrawText ("G : ", 580,210);
cs.DrawText ("B : ", 580,250);
ss1=intToString (cr);
ss2=intToString (cg);
ss3=intToString (cb);
tab=0 ; //put text center
if (cr<10) tab=12;
if (cr>9&&cr<100) tab=6 ;
cs.DrawText (ss1, 620+tab,170);
tab=0 ;
if (cg<10) tab=12;
if (cg>9&&cg<100) tab=6 ;
cs.DrawText (ss2, 620+tab,210);
tab=0 ;
if (cb<10) tab=12;
if (cb>9&&cb<100) tab=6 ;
cs.DrawText (ss3, 620+tab,250);
cs.DrawText ("H : 度", 580,310);
cs.DrawText ("S : % ", 580,350);
cs.DrawText ("B : % ", 580,390);
ss1=intToString (H);
ss2=intToString (S);
ss3=intToString (V);
tab=0 ;
if (H<10) tab=12;
if (H>9&&H<100) tab=6 ;
cs.DrawText (ss1, 620+tab,310);
tab=0 ;
if (S<10) tab=12;
if (S>9&&S<100) tab=6 ;
cs.DrawText (ss2, 620+tab,350);
tab=0 ;
if (V<10) tab=12;
if (V>9&&V<100) tab=6 ;
cs.DrawText (ss3, 620+tab,390);
cs.DrawText ("新的 ", 491,358);
cs.DrawText ("S ", 445,325);
cs.DrawText ("B ", 445,395);
//画按钮
cs.SetColor (255,120,120,120);
cs.DrawRect (570,450,664,489); //按钮
cs.DrawRect (460,450,554,489); //按钮
cs.SetColor (255,250,250,250);
cs.DrawRect (572,451,662,486); //按钮
cs.DrawRect (462,451,552,486); //按钮
cs.SetColor (255,200,200,200);
cs.DrawRect (574,454,662,487); //按钮
cs.DrawRect (464,454,552,487); //按钮
cs.SetColor (255,220,220,220);
cs.DrawRect (575,454,658,483); //按钮
cs.DrawRect (465,454,548,483); //按钮
cs.SetColor (255,0,0,0);
cs.SetTextSize (22);
cs.DrawText ("确 定 ", 595, 477);
cs.DrawText ("取 消 ", 485, 477);
//另外RGB选色可加调整小按钮+-选色
//也可使用scrollbar来设置,调节RGB色,
// S 选色条和 B 选色条联动显示选色
cs.SetColor (255,250,0,0); //调色按钮red
cs.DrawRect (667,147,690,163);
cs.DrawRect (667,164,690,180);
cs.SetColor (255,0,240,0); //调色按钮green
cs.DrawRect (667,187,690,203);
cs.DrawRect (667,204,690,220);
cs.SetColor (255,0,0,250); //调色按钮blue
cs.DrawRect (667,227,690,243);
cs.DrawRect (667,244,690,260);
cs.SetColor (255,250,250,250); //调色按钮
cs.DrawText ("+ ",672,162);
cs.DrawText ("-- ",672,178);
cs.DrawText ("+ ",672,202);
cs.DrawText ("-- ",672,218);
cs.DrawText ("+ ",672,242);
cs.DrawText ("-- ",672,258);
//题标,框线
cs.SetFillMode (0);//0不填色,1填色
cs.SetStrokeWidth(2); //线宽
cs.SetColor (255,190,190,190);
cs.DrawRect (50,80,560,280); //调色板框线
cs.SetStrokeWidth(1); //线宽
cs.DrawRect (610,80,665,135); //选色rgb框线
cs.DrawRect (50,304, 436,330); //选色条框线
cs.DrawRect (50,374, 436,400); //选色条框线
cs.DrawRect (467,303,552,400); //已选色
//print 题标
cs.SetTextSize (34);
cs.SetTextStyle (1) ;
cs.SetFillMode (1) ;
ss=" HSB 调色板设计 示例( 8 )" ;
cs.SetColor (255,0,150,0);
cs.DrawText (ss,54,574);
cs.SetColor (255,0,250,0);
cs.DrawText (ss,50,570);
cs.SetFillMode (0) ;
cs.SetColor (255,250,220,0);
cs.DrawText (ss,50,570);
cs.Update ();
}//colorpad8 ()
Hselect (){
//计算H值
// xpos1=50; xpos2=560; H 宽度 =560-50=510
//x1=px; y1=py; //mouse click new point px, py
// 510/360=1.41666
H=(int)((px-50)/1.4166) ;
//****计算如此简单,没深奥的公式 *****
//标记H值画游标,更新数值,更新选色块
cs.SetFillMode (1);//0不填色,1填色
cs.SetStrokeWidth(3);
cs.SetColor(255,110,110,110 );
cs.DrawRect (46,281,564,295); //擦除
cs.SetColor(255,255,0,0 );
cs.DrawRect (px-1,281,px+1,294); //游标
cs.DrawCircle (px,290,4) ;
cs.Update ();
//更新数值,显示
HRenew () ;
}//Hselect ()
HRenew (){ //依H值更新
//**** 计算HSV ********
//调色板尺寸:scale (50,80,560,280);
//mouse 调色板取色 xpos 计算 Hue 值
//计算也可加S饱和度设置,即二点距离 L长度(高)
//可计算取得 RGB 值,cr, cg, cb
//六段画调色板 255/3=85, 85*6=510 = 色板宽度
// 1. (255,255,i,0); //red-yellow 0 - 59
// 2. (255,255-i,255,0); //yellow-green 60 -119
// 3. (255,0,255,i); //green-blue 120-179
// 4. (255,0,255-i,255); //blue-purple 180-239
// 5. (255, i , 0,255); //purple-magenta 240-299
// 6. (255,255,0,255-i); //magenta-red 300-360
//依此6段设色,每段60度,可定RGB色
//* H色板显示mouse 选色,计算RGB (r,g,b)
cs.SetFillMode (1) ; //六类基色
if (H<=60) { //1. red
cr=255; cb=0;
cg=(int)(H*255/60) ; }
if (H>60&&H<=120) { //2. yellow
cg=255; cb=0;
cr=(int)(255-(H-60)*255/60) ; }
if (H>120&&H<=180) { //3. green
cr=0; cg=255;
cb=(int)((H-120)*255/60) ; }
if (H>180&&H<=240) { //4. cyan
cg=(int)(255-(H-180)*255/60 ) ;
cr=0 ; cb=255 ; }
if (H>240&&H<=300) { //5. blue
cr=(int)((H-240)*255/60 ) ;
cg=0 ; cb=255 ; }
if (H>300&&H<=360) { //6. magenta
cr=255; cg=0;
cb=(int)(255-(H-300)*255/60 ) ; }
r1=cr; g1=cg; b1=cb; //设置新的色rgb
//依选色值计算,显示取色
//选色显示:当前,新的
cs.SetFillMode (1) ;
cs.SetColor (255,cr, cg, cb ); //依选色显示
cs.DrawRect (612,82,664,134); //H板色show
cs.DrawRect (469,305,550,398); //新的选色
//取色后,S和V 的初始值是100。即选色条的中心位
S=100 ; V=100 ; //初始值
//H色板取色后,SB值和游标初始值均为100
//选色条颜色依所取色来绘出,六类基色1-6
//依据取色条的游标的xpos值计算 SV值
//游标 xpos=x1,x2, 100=435
//依H值的rgb绘制SV选色条:draw S,B bar
R=cr ; G=cg ; B=cb ;
cs.SetStrokeWidth(2);
for (i=0;i<=255 ;i++){ //调色板:选色条
R=R+i ; G=G+i ; B=B+i ;
if (R>255) R=255 ;
if (G>255) G=255 ;
if (B>255) B=255 ;
cs.SetColor (255, R, G, B ) ;
cs.DrawLine (435-i*1.5, 305,435-i*1.5,330);
R=R-i ; G=G-i ; B=B-i ;
if (R<0) R=0 ;
if (G<0) G=0 ;
if (B<0) B=0 ;
cs.SetColor (255, R, G, B ) ;
cs.DrawLine (435-i*1.5, 375,435-i*1.5, 400 ); }
//画游标
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,250,20,250);
x1=435 ; x2=435 ; //S, V值100=435
cs.SetStrokeWidth(2);
cs.SetColor (255,110,110,110); //擦除
cs.DrawRect (48,331,436,341); //游标尺1
cs.DrawRect (48,401,436,411); //游标尺1
cs.SetColor (255,250,0,0);
cs.DrawRect (x1-1,331,x1+1,337); //游标尺1
cs.DrawCircle (x1,337,4);
cs.DrawRect (x2-1,401,x2+1,407); //游标尺2
cs.DrawCircle (x2,407,4);
//更新值,显示数值
cs.SetTextStyle (0) ;
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,150,150,150);
cs.DrawRect (610,147,665,180); //标值底色
cs.DrawRect (610,187,665,220);
cs.DrawRect (610,227,665,260);
cs.DrawRect (610,287,665,320);
cs.DrawRect (610,327,665,360);
cs.DrawRect (610,367,665,400);
cs.SetColor (255,250,250,250);
cs.SetTextSize (20);
ss1=intToString (cr);
ss2=intToString (cg);
ss3=intToString (cb);
tab=0 ; //put text center
if (cr<10) tab=12;
if (cr>9&&cr<100) tab=6 ;
cs.DrawText (ss1, 620+tab,170);
tab=0 ;
if (cg<10) tab=12;
if (cg>9&&cg<100) tab=6 ;
cs.DrawText (ss2, 620+tab,210);
tab=0 ;
if (cb<10) tab=12;
if (cb>9&&cb<100) tab=6 ;
cs.DrawText (ss3, 620+tab,250);
ss1=intToString (H);
ss2=intToString (S);
ss3=intToString (V);
tab=0 ;
if (H<10) tab=12;
if (H>9&&H<100) tab=6 ;
cs.DrawText (ss1, 620+tab,310);
tab=0 ;
if (S<10) tab=12;
if (S>9&&S<100) tab=6 ;
cs.DrawText (ss2, 620+tab,350);
tab=0 ;
if (V<10) tab=12;
if (V>9&&V<100) tab=6 ;
cs.DrawText (ss3, 620+tab,390);
cs.Update ();
}//HRenew()
addPicture (){ //加底图
fname="/storage/emulated/0/form.jpg";
cs.DrawBitmap(fname,0,6); //加底图
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,0,0,0);
cs.DrawRect (0,2,720,22);
cs.DrawRect (0,2,12,570);
cs.DrawRect (0,570,720,600);
cs.SetColor (255,100,100,100);
cs.DrawRect (28,65,709,521); //大框线
cs.Update ();
}//addPicture()
SRenew (){ //S选色条点击拖动选色
//get S xpos=x1
V=100 ; x2=435 ;
S=(int)((x1-50)/2.55/1.5) ;
kn=(int)((100-S)*2.55) ;
r1=cr+kn ; g1=cg+kn ; b1=cb+kn ;
if (r1>255) r1=255 ;
if (g1>255) g1=255 ;
if (b1>255) b1=255 ;
cs.SetColor (255, r1, g1, b1);
cs.DrawRect (469,305,550,398); //新的选色
//画游标,更新 SV 值
cs.SetFillMode (1);//0不填色,1填色
//S, V初值100=435
cs.SetStrokeWidth(2);
cs.SetColor (255,110,110,110); //擦除
cs.DrawRect (46,331,439,342); //游标尺1
cs.DrawRect (46,401,439,411); //游标尺2
cs.SetColor (255,250,0,0);
cs.SetColor (255,250,0,0);
cs.DrawRect (x1-1,331,x1+1,337); //游标尺1
cs.DrawCircle (x1,337,4);
cs.DrawRect (x2-1,401,x2+1,407); //游标尺2
cs.DrawCircle (x2,407,4);
cs.SetTextSize (20);
cs.SetTextStyle (0) ;
cs.SetColor (255,150,150,150);
cs.DrawRect (610,327,665,360);
cs.DrawRect (610,367,665,400);
cs.SetColor (255,250,250,250);
ss2=intToString (S);
ss3=intToString (V);
tab=0 ;
if (S<10) tab=12;
if (S>9&&S<100) tab=6 ;
cs.DrawText (ss2, 620+tab,350);
tab=0 ;
if (V<10) tab=12;
if (V>9&&V<100) tab=6 ;
cs.DrawText (ss3, 620+tab,390);
cs.Update ();
}//SRenew ()
VRenew (){ //V选色条点击拖动选色
//* get V xpos=x2
S=100 ; x1=435 ;
V=(int)((x2-50)/2.55/1.5) ;
kn=(int)((100-V)*2.55) ;
r1=cr-kn ; g1=cg-kn ; b1=cb-kn ;
if (r1<0) r1=0 ;
if (g1<0) g1=0 ;
if (b1<0) b1=0 ;
cs.SetColor (255, r1, g1, b1);
cs.DrawRect (469,305,550,398); //新的选色
//画游标,更新SV值
cs.SetFillMode (1);//0不填色,1填色
cs.SetColor (255,250,20,250);
//S, V初值100=435
cs.SetStrokeWidth(2);
cs.SetColor (255,110,110,110); //擦除
cs.DrawRect (46,331,439,342); //游标尺1
cs.DrawRect (46,401,439,411); //游标尺2
cs.SetColor (255,250,0,0);
cs.SetColor (255,250,0,0);
cs.DrawRect (x1-1,331,x1+1,337); //游标尺1
cs.DrawCircle (x1,337,4);
cs.DrawRect (x2-1,401,x2+1,407); //游标尺2
cs.DrawCircle (x2,407,4);
cs.SetTextSize (20);
cs.SetTextStyle (0) ;
cs.SetColor (255,150,150,150);
cs.DrawRect (610,327,665,360);
cs.DrawRect (610,367,665,400);
cs.SetColor (255,250,250,250);
ss2=intToString (S);
ss3=intToString (V);
tab=0 ;
if (S<10) tab=12;
if (S>9&&S<100) tab=6 ;
cs.DrawText (ss2, 620+tab,350);
tab=0 ;
if (V<10) tab=12;
if (V>9&&V<100) tab=6 ;
cs.DrawText (ss3, 620+tab,390);
cs.Update ();
}//VRenew ()
//**** End ********