• <tfoot id="ukgsw"><input id="ukgsw"></input></tfoot>
    
    • 久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
      分享

      HSL顏色處理

       我的菜譜123 2013-07-12

       

      顏色的規律,個人理解 純屬扯淡 見諒。有些網上抄的 炒剩飯。

      知識的海洋很深奧 就像一個神奇的盒子 貌似理解了 可能有些東西再過幾年都沒能理解

      顏色模式

      色彩是由物體所反射光的波長來決定的

      RGB加色模式

       

      RGB為三個能量值 能量值的強弱直觀的反映了明與暗 能量值越強越亮

       

      而CMY減色模式是跟RGB互逆的一種方式

      介質是白的 然后要把顏料涂上去 展現各種色彩。

      物體是什么 物體可以反射光 但同時也要吸收一定的能量值,

      所以從本質上看把顏料涂上去是一個變暗的過程。CMY正符合了這種原理。

      你看RGB三原色交叉部分不正是CMY嗎 自然界是多么的神奇。

       

      HSB(HSL) 色調飽和度亮度模式

      以另外一種不同的理念進行色彩的調配

      H色調 0~360 圓環形式 以角度表示

      S 飽和度 0~1 之間的小數

      L 亮度 0~1 之間的小數

       

      什么是純色

      先來看一下windows的拾色器

       

      最上頭黑色框里面那些顏色 最最最頂端的部分。

      是不是感覺他們最鮮艷 最惹眼,嗯 因為他們RGB之間的差異化最大

      RGB產生顏色的原理就是RGB三個能量值產生差異化 組合。

      所以我們才能看到這些花花綠綠的顏色。

      純色一個特點那就是最大值跟最小值的差是255 ,差異達到最大。

      也就是說RGB一定有一個顏色是0 一個是255,否則不能稱之為純色

      純亮度表示就是只能量值沒有差異 也指灰度圖

       

      在液晶屏上以仰視的角度看上面的那幅圖  你會看到底部飽和度比較低的部分。TFT屏幕都是這樣 可視角度比較差

      就像這樣的效果:

       

      這就是為什么確定RGB為三基色,其實我也不懂 但是看了上圖估計也不需要過多的技術解釋了吧。

       

      純色的計算

      通過觀察windows畫圖板拾色器 就是上面中間那個破圖。我們知道 如果飽和度固定為1 亮度固定為0.5 ,那么色調即純色 純色即色調。純色的定義參見上面。

      從RGB值的變化規律可以看出色調的變化是連續平緩 首尾相接的 可以看成是一個360度的圓 紅色是0度。他的變化規律是:

       

      又是看圖

      這鬼的規律啊 哪有什么規律 花花綠綠好看吧 有點像披薩,說錯了 有點像燒餅。

      三個規律

      1至始至終都有一個值是0 一個值是255。

      2整個過程中同一時間總是只有一個值在變

      3三個數的全排列 那么總共有6種組合

      形象點來說

      有一個值在增加 增滿過后另一個值再增加 本值再減小 就像這樣從左往右 以長江后浪推前浪 前仆后繼的方式達到原點  有點像合金彈頭游戲里面那種循環的無縫銜接背景 哥們兒你聽懂我在說什么了嗎。其實我也沒搞懂自己在說什么。

       

      通過以上我們寫段代碼枚舉一些個純色

      但是首先有一點要明確: 就是那塊披薩 就是60度 值是255

      我們把色調分成1~360的表現形式,但是RGB是以(255,255,255)的表現形式 那么他們之間怎么對應呢?那就是60度=255

      每前進一度scale =(255*6)*(1/360)

      RGB可以表達255*255*255=16581375種顏色 但是他可以表達的純色只有255*6=1530種

       

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      public void getHue()
      {
          Graphics gph = Graphics.FromHwnd(this.Handle);
          int indx = 0;
        
          //狀態是Up 顏色是綠色 這已經很明顯了吧,這正是0度時候推進的趨勢
          bool high = true;//Up
          int scale = 1;//0紅色 1綠色 2藍色
          int[] cor = { 255, 0, 0 };//0度角 紅色
        
          Color[] cors = new Color[36];
          Color result = Color.FromArgb(cor[0], cor[1], cor[2]);
          int curScale = 0;
          //推進以便 生成所有色調的顏色表
          //這里的30指前進30步 與其他并無關系
          //具體前進的范圍為: 步數*(255D * 6 * (每步的大小 / 360D))
          //注意每步大小的值不能超過60 因為60=255 scale的值域是[0,255]
          while (indx < 30)
          {
              if (high == true)
              {
                  curScale = scale % 3;
                  cor[curScale] = (int)(255D * 6 * (10 / 360D));
              }
              else if (high == false)
              {
                  curScale = (scale - 1) % 3;//< 0 ? 0 : (scale - 1) % 3;
                  cor[curScale] -= (int)(255D * 6 * (10 / 360D));
              }
        
              gph.DrawString(indx.ToString(), new Font(new FontFamily("宋體"), 9), new SolidBrush(Color.Black), 15 * (indx - 1), 50);
        
              if (cor[curScale] < 0)
              {
                  cor[curScale] = 0;
                  scale ;
                  high = !high;
                  gph.DrawString("▓", new Font(new FontFamily("宋體"), 9), new SolidBrush(Color.Black), 15 * (indx - 1), 90);
                  continue;
              }
              else if (cor[curScale] > 255)
              {
                  cor[curScale] = 255;
                  //scale ;
                  high = !high;
                  gph.DrawString("▇ ", new Font(new FontFamily("宋體"), 9), new SolidBrush(Color.Black), 15 * (indx - 1), 90);
                  continue;
              }
        
              cors[indx] = Color.FromArgb(cor[0], cor[1], cor[2]);
              gph.FillRectangle(new SolidBrush(Color.FromArgb(cor[0], cor[1], cor[2])), 15 * indx , 0, 15, 20);
              gph.DrawString(curScale.ToString(), new Font(new FontFamily("宋體"), 9), new SolidBrush(Color.Black), 15 * (indx - 1), 30);
        
              gph.DrawString(scale.ToString(), new Font(new FontFamily("宋體"), 9), new SolidBrush(Color.Black), 15 * (indx - 1), 70);
          }
      }

       

       

       

      增加他們之間的密度 越密過度越平滑

      最平滑的狀況是 scale =1

       

      越稀 則越粗糙 他的極限是 scale =(255*6)*(60/360)

      即 scale =255 超過255是無意義的 因為scale的取值是0~255

       

      別看幾句破代碼 調試的時候可是費了我好大勁兒。

       

      我們已經能枚舉所有色調,實際上他是一個從0度(255,0,0)偏移的過程。但是更改色調有沒有一種快速的方式計算呢。難道每確定一個顏色都進行255*6=1530次循環?不會吧。

      自然不會 但是最多進行6次循環是必須的 因為網上的公式也要進行6個switch 囧 說明磚家該研究的早就研究過了 咱不可能超過磚家 對吧。

      快速計算的方式就是~~~ 加速每次偏轉的值 更改偏轉的次數 嗯 條件是不少于6次。怎么樣換湯不換藥吧~~~ 囧

       

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      public Color getHue(int theta)//角度0~360
      {
          int times = theta / 60, Mod = theta % 60;
          bool high = true;
          int scale = 1, indx = 0;
          int[] cor = { 255, 0, 0 };
          int curScale = 0;
          while (indx <times )
          {
              
              if (high == true)
              {
                  curScale = scale % 3;
                  cor[curScale] = 255 ;
              }
              else if (high == false)
              {
                  curScale = (scale - 1) % 3;
                  cor[curScale] -= 255 ;
              }
              
              if (cor[curScale] <= 0)
              {
                  cor[curScale] = 0;
                  scale ;
                  high = !high;
              }
              else if (cor[curScale] >= 255)
              {
                  cor[curScale] = 255;
                  high = !high;
              }
              indx ;
          }
        
          if (high == true)
              cor[scale % 3] = (int)(255D * 6 * (Mod / 360D)) > 255 ? 255 : (int)(255D * 6 * (Mod / 360D));
          else if (high == false)
              cor[(scale - 1) % 3] -= (int)(255D * 6 * (Mod / 360D)) < 0 ? 0 : (int)(255D * 6 * (Mod / 360D));
          
          return Color.FromArgb(cor[0], cor[1], cor[2]);
      }

       


       

       

      純色 飽和度 HSL RGB 他們之間到底有什么奧秘

      我們來做個windows畫圖板那樣的拾色器順便 測試下上面函數的正確性

       

      色調有了 然后就是處理飽和度

      這個規律比色調那個簡單多了

      還是通過觀察拾色器

      R2為處理后的值 R1為處理前的值 :R2=R1 (127-R1)*S

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      public void drawPalette()
      {
          Graphics gph = Graphics.FromHwnd(this.Handle);
          //生成顏色表
          Color[] cors = new Color[(int)(360D / 11)];
          for (int i = 0; i < 360 - 11; i = 11)
              cors[(i / 11)] = getHue(i);
        
          //飽和度處理
          float s = 0;//飽和度
          for (int i = 0; i < 20; i )//10行 10個等級的飽和度
          {
              for (int j = 0; j < cors.Length; j )//顏色數
              {
                  //計算方式 r'=r (127-r)s
                  Color corTmp = Color.FromArgb((int)(cors[j].R (127 - cors[j].R) * s),
                      (int)(cors[j].G (127 - cors[j].G) * s),
                      (int)(cors[j].B (127 - cors[j].B) * s));
        
                  gph.FillRectangle(new SolidBrush(corTmp), 15 * j, 15 * i, 15, 15);
              }
              s = (1f / 20);
          }
        
          //this.BackColor = getHue(59);//10 * i
      }

       


       

       

      但是有一點要說明下 如果一幅圖像的色調降得很低了接近灰度了 說明他的顏色信息已經損失了 再去還原他的色調是有困難的

       

      上圖雖然已經達到我們要的目的了,但是我們就是愛折騰 就是要讓他不一樣 ~~

      把for循環里面的顏色計算代碼改成這樣:

      1
      2
      3
      4
      5
      Color corTmp = Color.FromArgb((int)(cors[j].R (255 - cors[j].R) * s),
                      (int)(cors[j].G (0 - cors[j].G) * s),
                      (int)(cors[j].B (0 - cors[j].B) * s));

       


       

       

      這反映了一個現象 雖然某些顏色看上去不是紅色

      但是他三基色的組成里紅色成分越多被侵蝕就越嚴重 紅色成分越少越抗侵蝕,看 多么的完美 這與photoshop里的調色常識不謀而合。

       

      說道他們的奧秘嘛 ,咳咳咳 。其實也沒什么奧秘

      總結下:

      飽和度度/彩度 指顏色信息 降低容易 降低到一定程度 還原可就難了。

      色調其實是指飽和度為1 亮度為0.5的 這種特例情況 也指純色。純色定義見前面

      亮度、飽和度的調整 都是以純色為初始的 所以找出純色很關鍵。

      從純色算法以及能量值差異原理可以知道 色調主要跟RGB里的最大值最小值相關 他們之間的差異反映了色調 他們跟另外一個值進行調配 反映了飽和度。最大值的強弱反映了可見度 即亮度。

      何以見得呢。

      調用.net自帶的函數得到飽和度

      Color c = Color.FromArgb(210, 23, 232);

      MessageBox.Show(c.GetSaturation().ToString());

      輸出結果是0.8196079

      你可以試驗一下把210改到(23,232)范圍內的任意值 最后輸出的結果都是一樣的。

       

       

      網上寫的那些公式

       

       

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      public Color getRGBfromHSV(double _h, double _s, double _v)//色相 飽和度 亮度
      {
          int h1 = (int)(_h / 60 % 6);//確定色調在色帶中的位置 其實就是確定色調
          double f = _h / 60 - h1;
      //確定最大值最小值 亮度
          double p = (_v * (1 - _s));
          double q = (_v * (1 - f * _s));
          double t = (_v * (1 - (1 - f) * _s));
        
      Color cor;
      //按色調對這些值進行分配
          switch (h1)
          {
              case 0:
                  cor = Color.FromArgb((int)(_v * 255), (int)(t * 255), (int)(p * 255));
                  break;
              case 1:
                  cor = Color.FromArgb((int)(q * 255), (int)(_v * 255), (int)(p * 255));
                  break;
              case 2:
                  cor = Color.FromArgb((int)(p * 255), (int)(_v * 255), (int)(t * 255));
                  break;
              case 3:
                  cor = Color.FromArgb((int)(p * 255), (int)(q * 255), (int)(_v * 255));
                  break;
              case 4:
                  cor = Color.FromArgb((int)(t * 255), (int)(p * 255), (int)(_v * 255));
                  break;
              default:
                  cor = Color.FromArgb((int)(_v * 255), (int)(p * 255), (int)(q * 255));
                  break;
          }
          return cor;
      }

       


       

      我照著公式的原理寫了段代碼 神了 確實可以用 但是說實話我真沒搞太懂。看問題要研究他的本質 不能老抄別人的。

       

       另一段改自C 的轉換代碼:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      public Color GetRGBColorFromHSV(double _h, double _s, double _v)//色相 飽和度 亮度
      {
          double r, g, b;
          if (_s == 0)//如果飽和度為0則是灰度圖 rgb三個值都將等于亮度
          {
              r = _v;
              g = _v;
              b = _v;
          }
          else
          {
              double[] dp = new double[3];
              double xh = _h * 6;//色相x6 ?
              if (xh == 6) xh = 0;//色環是一個360度的圓環 如果超過最大值則變為0
              //int i = (int)(Math.Floor(xh) 0.1);//色相x6取整數 0.1 ?
              int i = (int)xh;
              dp[0] = 1; dp[2] = 0; xh -= i;
              if (i % 2 != 0)// (i&1) //如果i是奇數
                  dp[1] = 1 - xh;
              else
                  dp[1] = xh;
              //處理色調
              for (int n = 0; n < 3; n)
              {
                  dp[n] = (((dp[n]) - 0.5) * (_s) 0.5);
                  //SATFORMAT(dp[n], _s);
              }
              //處理亮度
              if (_v == 0.5) { }
              else if (_v < 0.5)
              {
                  if (_v < 0) _v = 0;
                  for (int n = 0; n < 3; n)
                      dp[n] = ((dp[n]) * (_v) * 2);
                  //BLACKFORMAT(dp[n], _v)
              }
              else
              {
                  if (_v > 1) _v = 1;
                  for (int n = 0; n < 3; n)
                      dp[n] = (1 - (1 - (dp[n])) * (1 - (_v)) * 2);
                  //WHITEFORMAT(dp[n], _v);
              }
              //三個元素的全排列 ?
              switch (i)
              {
                  case 0:
                      r = dp[0]; g = dp[1]; b = dp[2];
                      break;
                  case 1:
                      r = dp[1]; g = dp[0]; b = dp[2];
                      break;
                  case 2:
                      r = dp[2]; g = dp[0]; b = dp[1];
                      break;
                  case 3:
                      r = dp[2]; g = dp[1]; b = dp[0];
                      break;
                  case 4:
                      r = dp[1]; g = dp[2]; b = dp[0];
                      break;
                  default:
                      r = dp[0]; g = dp[2]; b = dp[1];
                      break;
              }
               
          }
          //return ((int)(b * 255 .5) << 16) ((int)(g * 255 .5) << 8) (int)(r * 255 .5);
          Color cor = Color.FromArgb((int)(r * 255 0.5), ((int)(g * 255 0.5)), ((int)(b * 255 0.5)));
          return cor;
      }

       調用上面的函數來整點花哨的效果 一個圓環形的色帶:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      Class1 c2 = new Class1();
      Graphics gph = Graphics.FromHwnd(this.Handle);
      Color[] cors = new Color[360];
      gph.TranslateTransform(200, 200);
      System.Drawing.Drawing2D.GraphicsPath ph = new System.Drawing.Drawing2D.GraphicsPath();
      ph.AddEllipse(-100, -100, 200, 200);
      ph.AddEllipse(-80, -80, 160, 160);
      gph.SetClip(ph, System.Drawing.Drawing2D.CombineMode.Intersect);
      for (int k = 0; k < 360; k )
      {
          cors[k] = c2.GetRGBColorFromHSV(1D/360 * k, 1D, 0.5D);
          gph.RotateTransform(1);
          gph.DrawLine(new Pen(new SolidBrush(cors[k]), 2), 0, 0, 100, 0);
      }
      gph.FillEllipse(new SolidBrush(Color.Transparent), -80, -80, 160, 160);

       

       

      亮度部分我暫時不想寫了 累了 下次補上。

      亮度0.5是個分水嶺 高于0.5的時候RGB三個值都是增的趨勢 低于0.5時是減的趨勢

       

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發表

        請遵守用戶 評論公約

        主站蜘蛛池模板: 40岁大乳的熟妇在线观看| 亚洲熟女乱色一区二区三区| 国产精品青青在线观看爽香蕉| 久久综合九色欧美综合狠狠| 天堂亚洲免费视频| 国产女精品视频网站免费蜜芽| 亚洲欧美人成网站在线观看看| 国产超碰无码最新上传| 成在人线AV无码免观看| 精品人妻无码专区在中文字幕| 久久久久亚洲AV成人网人人软件 | 无码国产69精品久久久久孕妇 | 最新日韩精品中文字幕| 亚洲一卡2卡3卡4卡精品| 色橹橹欧美在线观看视频高清 | 疯狂做受XXXX高潮国产| 欧美黑人XXXX性高清版| 大地资源中文第二页日本| 日韩在线视频线观看一区| 久久99国产精品久久99小说| 99久久99久久加热有精品| 在线免费成人亚洲av| 狠狠色丁香婷婷综合潮喷| 国产高清在线不卡一区| 色婷婷综合久久久久中文字幕| 在线 欧美 中文 亚洲 精品| 国产精品一亚洲AV日韩AV欧 | 又爽又黄又无遮挡的激情视频| 国产成人亚洲精品无码电影不卡| 亚洲综合一区国产精品| 换着玩人妻中文字幕| 99在线精品国自产拍中文字幕| 女上男下激烈啪啪无遮挡| 白色丝袜国产在线视频| 暖暖日本手机免费观看中文| 国产精品毛片无码| 精品一区二区三区在线播放视频| 国产午夜福利视频合集| 国产精品国产精品国产专区不卡| 国产曰批视频免费观看完| 2021国产精品视频网站|