• Delphi图像处理 -- RGB与HSL转换


    阅读提示:

        《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。

        《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。

        尽可能保持二者内容一致,可相互对照。

        本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元。

    [delphi] view plain copy
     
    1. const  
    2.   _fc0: Single    = 0.0;  
    3.   _fcd5: Single   = 0.5;  
    4.   _fc1: Single    = 1.0;  
    5.   _fc2: Single    = 2.0;  
    6.   _fc6: Single    = 6.0;  
    7.   _fc60: Single   = 60.0;  
    8.   _fc255: Single  = 255.0;  
    9.   _fc360: Single  = 360.0;  
    10.   _fc510: Single  = 510.0;  
    11.   
    12. procedure ColorToHSL(var H, S, L: Single; Color: TARGB);  
    13. var  
    14.   rgbMax: LongWord;  
    15. asm  
    16.     push      eax  
    17.     push      edx  
    18.     push      ecx  
    19.     movzx     ecx, Color.TARGBQuad.Blue  
    20.     movzx     edx, Color.TARGBQuad.Green  
    21.     movzx     eax, Color.TARGBQuad.Red  
    22.     cmp       ecx, edx        // ecx = rgbMax  
    23.     jge       @@1             // edx = rgbMin  
    24.     xchg      ecx, edx  
    25. @@1:  
    26.     cmp       ecx, eax  
    27.     jge       @@2  
    28.     xchg      ecx, eax  
    29. @@2:  
    30.     cmp       edx, eax  
    31.     cmova     edx, eax  
    32.     mov       rgbMax, ecx  
    33.     mov       eax, ecx  
    34.     add       ecx, edx        // ecx = rgbMax + rgbMin  
    35.     sub       eax, edx        // delta = rgbMax - rgbmin  
    36.     cvtsi2ss  xmm0, ecx  
    37.     divss     xmm0, _fc510  
    38.     pop       edx  
    39.     movss     [edx], xmm0     // *L = (rgbMax + rgbMin) / 255 / 2  
    40.     jnz       @@3  
    41.     pop       ecx             // if (delta == 0)  
    42.     pop       edx             // {  
    43.     mov       [ecx], eax      //   *H = *S = 0  
    44.     mov       [edx], eax      //   return  
    45.     jmp       @@Exit          // }  
    46. @@3:  
    47.     comiss    xmm0, _fcd5  
    48.     jb        @@4  
    49.     neg       ecx  
    50.     add       ecx, 510        // if (L < 128) ecx = 510 - ecx  
    51. @@4:  
    52.     pop       edx  
    53.     cvtsi2ss  xmm0, eax  
    54.     cvtsi2ss  xmm1, ecx  
    55.     movaps    xmm2, xmm0  
    56.     divss     xmm0, xmm1  
    57.     movss     [edx], xmm0     // *S = delta / ecx  
    58.     mov       eax, rgbMax  
    59.     cmp       al, Color.TARGBQuad.Red  
    60.     jne       @@5  
    61.     movzx     eax, Color.TARGBQuad.Green  
    62.     movzx     edx, Color.TARGBQuad.Blue  
    63.     xor       ecx, ecx        // if (R == rgbMax) eax = G - B; add = 0  
    64.     jmp       @@7  
    65. @@5:  
    66.     cmp       al, Color.TARGBQuad.Green  
    67.     jne       @@6  
    68.     movzx     eax, Color.TARGBQuad.Blue  
    69.     movzx     edx, Color.TARGBQuad.Red  
    70.     mov       ecx, 120         // if (G == rgbMax) eax = B - R; add = 120  
    71.     jmp       @@7  
    72. @@6:  
    73.     movzx     eax, Color.TARGBQuad.Red  
    74.     movzx     edx, Color.TARGBQuad.Green  
    75.     mov       ecx, 240         // if (B == rgbMax) eax = R - G; add = 240  
    76. @@7:  
    77.     sub       eax, edx  
    78.     cvtsi2ss  xmm0, eax  
    79.     cvtsi2ss  xmm1, ecx  
    80.     mulss     xmm0, _fc60  
    81.     divss     xmm0, xmm2  
    82.     addss     xmm0, xmm1      // H = eax * 60 / delta + add  
    83.     comiss    xmm0, _fc0  
    84.     jae       @@8  
    85.     addss     xmm0, _fc360  
    86. @@8:  
    87.     pop       eax  
    88.     movss     [eax], xmm0  
    89. @@Exit:  
    90. end;  
    91.   
    92. function HSLToColor(H, S, L: Single): TARGB;  
    93. asm  
    94.     movss     xmm0, H  
    95.     comiss    xmm0, _fc0  
    96.     jae       @@1  
    97.     addss     xmm0, _fc360  
    98.     jmp       @@2  
    99. @@1:  
    100.     comiss    xmm0, _fc360  
    101.     jb        @@2  
    102.     subss     xmm0, _fc360  
    103. @@2:  
    104.     movss     xmm3, _fc1  
    105.     divss     xmm0, _fc60  
    106.     cvtss2si  edx, xmm0       // index = Round(H)  
    107.     cvtsi2ss  xmm1, edx  
    108.     subss     xmm0, xmm1      // extra = H - index  
    109.     comiss    xmm0, _fc0      // if (extra < 0) // 如果index发生五入  
    110.     jae       @@3             // {  
    111.     dec       edx             //   index --  
    112.     addss     xmm0, xmm3      //   extra ++  
    113. @@3:                          // }  
    114.     test      edx, 1  
    115.     jz        @@4  
    116.     movaps    xmm1, xmm0  
    117.     movaps    xmm0, xmm3  
    118.     subss     xmm0, xmm1      // if (index & 1) extra = 1 - extra  
    119. @@4:  
    120.     movss     xmm2, S  
    121.     movss     xmm4, L  
    122.     minss     xmm2, xmm3  
    123.     minss     xmm4, xmm3  
    124.     maxss     xmm2, _fc0  
    125.     maxss     xmm4, _fc0  
    126.     pslldq    xmm0, 4         //            max  mid  min  
    127.     movlhps   xmm0, xmm3      // xmm0 = 0.0 1.0 extra 0.0  
    128.     movaps    xmm1, xmm0  
    129.     subss     xmm3, xmm2  
    130.     movss     xmm2, _fcd5  
    131.     pshufd    xmm2, xmm2, 0  
    132.     pshufd    xmm3, xmm3, 0  
    133.     subps     xmm1, xmm2  
    134.     mulps     xmm1, xmm3  
    135.     subps     xmm0, xmm1      // xmm0 = xmm0 - (xmm0 - 0.5) * (1.0 - S);  
    136.     movaps    xmm1, xmm0  
    137.     subss     xmm4, xmm2  
    138.     mulss     xmm4, _fc2      // xmm4 = (L - 0.5) * 2  
    139.     comiss    xmm4, _fc0  
    140.     jb        @@5  
    141.     movss     xmm0, _fc1  
    142.     pshufd    xmm0, xmm0, 0  
    143.     subps     xmm0, xmm1      // if (xmm4 >= 0) xmm0 = 1 - xmm0  
    144. @@5:  
    145.     movss     xmm3, _fc255  
    146.     pshufd    xmm4, xmm4, 0  
    147.     pshufd    xmm3, xmm3, 0  
    148.     mulps     xmm0, xmm4  
    149.     addps     xmm0, xmm1  
    150.     mulps     xmm0, xmm3      // xmm0 = (xmm0 + xmm0 * xmm4) * 255  
    151.     jmp       @@jmpTable[edx*4].Pointer  
    152. @@jmpTable:   dd  offset  @@H60  
    153.               dd  offset  @@H120  
    154.               dd  offset  @@H180  
    155.               dd  offset  @@H240  
    156.               dd  offset  @@H300  
    157.               dd  offset  @@H360  
    158. @@H360:                       // 300 - 359  
    159.     pshufd    xmm0, xmm0, 11100001b  
    160.     jmp       @@H60  
    161. @@H300:                       // 240 - 299  
    162.     pshufd    xmm0, xmm0, 11010010b  
    163.     jmp       @@H60  
    164. @@H240:                       // 180 - 239  
    165.     pshufd    xmm0, xmm0, 11000110b  
    166.     jmp       @@H60  
    167. @@H180:                       // 120 - 179  
    168.     pshufd    xmm0, xmm0, 11001001b  
    169.     jmp       @@H60  
    170. @@H120:                       // 60 - 119  
    171.     pshufd    xmm0, xmm0, 11011000b  
    172. @@H60:                        // 0 - 59  
    173.     cvtps2dq  xmm0, xmm0  
    174.     packssdw  xmm0, xmm0  
    175.     packuswb  xmm0, xmm0  
    176.     movd      eax, xmm0  
    177.     or        eax, 0ff000000h  
    178. end;  

        《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。

  • 相关阅读:
    git stash
    vim 使用
    git 分支管理
    git 日常使用
    js createElement
    git checkout
    2.2链表 链表中倒数第k个结点
    1.8字符串及分析 翻转子串
    全排列
    1.7数组 清除行列
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/9055351.html
Copyright © 2020-2023  润新知