zoukankan      html  css  js  c++  java
  • Delphi图像处理 -- RGB与HSL转换

    阅读提示:

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

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

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

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

    const
      _fc0: Single    = 0.0;
      _fcd5: Single   = 0.5;
      _fc1: Single    = 1.0;
      _fc2: Single    = 2.0;
      _fc6: Single    = 6.0;
      _fc60: Single   = 60.0;
      _fc255: Single  = 255.0;
      _fc360: Single  = 360.0;
      _fc510: Single  = 510.0;
    
    procedure ColorToHSL(var H, S, L: Single; Color: TARGB);
    var
      rgbMax: LongWord;
    asm
        push      eax
        push      edx
        push      ecx
        movzx     ecx, Color.TARGBQuad.Blue
        movzx     edx, Color.TARGBQuad.Green
        movzx     eax, Color.TARGBQuad.Red
        cmp       ecx, edx        // ecx = rgbMax
        jge       @@1             // edx = rgbMin
        xchg      ecx, edx
    @@1:
        cmp       ecx, eax
        jge       @@2
        xchg      ecx, eax
    @@2:
        cmp       edx, eax
        cmova     edx, eax
        mov       rgbMax, ecx
        mov       eax, ecx
        add       ecx, edx        // ecx = rgbMax + rgbMin
        sub       eax, edx        // delta = rgbMax - rgbmin
        cvtsi2ss  xmm0, ecx
        divss     xmm0, _fc510
        pop       edx
        movss     [edx], xmm0     // *L = (rgbMax + rgbMin) / 255 / 2
        jnz       @@3
        pop       ecx             // if (delta == 0)
        pop       edx             // {
        mov       [ecx], eax      //   *H = *S = 0
        mov       [edx], eax      //   return
        jmp       @@Exit          // }
    @@3:
        comiss    xmm0, _fcd5
        jb        @@4
        neg       ecx
        add       ecx, 510        // if (L < 128) ecx = 510 - ecx
    @@4:
        pop       edx
        cvtsi2ss  xmm0, eax
        cvtsi2ss  xmm1, ecx
        movaps    xmm2, xmm0
        divss     xmm0, xmm1
        movss     [edx], xmm0     // *S = delta / ecx
        mov       eax, rgbMax
        cmp       al, Color.TARGBQuad.Red
        jne       @@5
        movzx     eax, Color.TARGBQuad.Green
        movzx     edx, Color.TARGBQuad.Blue
        xor       ecx, ecx        // if (R == rgbMax) eax = G - B; add = 0
        jmp       @@7
    @@5:
        cmp       al, Color.TARGBQuad.Green
        jne       @@6
        movzx     eax, Color.TARGBQuad.Blue
        movzx     edx, Color.TARGBQuad.Red
        mov       ecx, 120         // if (G == rgbMax) eax = B - R; add = 120
        jmp       @@7
    @@6:
        movzx     eax, Color.TARGBQuad.Red
        movzx     edx, Color.TARGBQuad.Green
        mov       ecx, 240         // if (B == rgbMax) eax = R - G; add = 240
    @@7:
        sub       eax, edx
        cvtsi2ss  xmm0, eax
        cvtsi2ss  xmm1, ecx
        mulss     xmm0, _fc60
        divss     xmm0, xmm2
        addss     xmm0, xmm1      // H = eax * 60 / delta + add
        comiss    xmm0, _fc0
        jae       @@8
        addss     xmm0, _fc360
    @@8:
        pop       eax
        movss     [eax], xmm0
    @@Exit:
    end;
    
    function HSLToColor(H, S, L: Single): TARGB;
    asm
        movss     xmm0, H
        comiss    xmm0, _fc0
        jae       @@1
        addss     xmm0, _fc360
        jmp       @@2
    @@1:
        comiss    xmm0, _fc360
        jb        @@2
        subss     xmm0, _fc360
    @@2:
        movss     xmm3, _fc1
        divss     xmm0, _fc60
        cvtss2si  edx, xmm0       // index = Round(H)
        cvtsi2ss  xmm1, edx
        subss     xmm0, xmm1      // extra = H - index
        comiss    xmm0, _fc0      // if (extra < 0) // 如果index发生五入
        jae       @@3             // {
        dec       edx             //   index --
        addss     xmm0, xmm3      //   extra ++
    @@3:                          // }
        test      edx, 1
        jz        @@4
        movaps    xmm1, xmm0
        movaps    xmm0, xmm3
        subss     xmm0, xmm1      // if (index & 1) extra = 1 - extra
    @@4:
        movss     xmm2, S
        movss     xmm4, L
        minss     xmm2, xmm3
        minss     xmm4, xmm3
        maxss     xmm2, _fc0
        maxss     xmm4, _fc0
        pslldq    xmm0, 4         //            max  mid  min
        movlhps   xmm0, xmm3      // xmm0 = 0.0 1.0 extra 0.0
        movaps    xmm1, xmm0
        subss     xmm3, xmm2
        movss     xmm2, _fcd5
        pshufd    xmm2, xmm2, 0
        pshufd    xmm3, xmm3, 0
        subps     xmm1, xmm2
        mulps     xmm1, xmm3
        subps     xmm0, xmm1      // xmm0 = xmm0 - (xmm0 - 0.5) * (1.0 - S);
        movaps    xmm1, xmm0
        subss     xmm4, xmm2
        mulss     xmm4, _fc2      // xmm4 = (L - 0.5) * 2
        comiss    xmm4, _fc0
        jb        @@5
        movss     xmm0, _fc1
        pshufd    xmm0, xmm0, 0
        subps     xmm0, xmm1      // if (xmm4 >= 0) xmm0 = 1 - xmm0
    @@5:
        movss     xmm3, _fc255
        pshufd    xmm4, xmm4, 0
        pshufd    xmm3, xmm3, 0
        mulps     xmm0, xmm4
        addps     xmm0, xmm1
        mulps     xmm0, xmm3      // xmm0 = (xmm0 + xmm0 * xmm4) * 255
        jmp       @@jmpTable[edx*4].Pointer
    @@jmpTable:   dd  offset  @@H60
                  dd  offset  @@H120
                  dd  offset  @@H180
                  dd  offset  @@H240
                  dd  offset  @@H300
                  dd  offset  @@H360
    @@H360:                       // 300 - 359
        pshufd    xmm0, xmm0, 11100001b
        jmp       @@H60
    @@H300:                       // 240 - 299
        pshufd    xmm0, xmm0, 11010010b
        jmp       @@H60
    @@H240:                       // 180 - 239
        pshufd    xmm0, xmm0, 11000110b
        jmp       @@H60
    @@H180:                       // 120 - 179
        pshufd    xmm0, xmm0, 11001001b
        jmp       @@H60
    @@H120:                       // 60 - 119
        pshufd    xmm0, xmm0, 11011000b
    @@H60:                        // 0 - 59
        cvtps2dq  xmm0, xmm0
        packssdw  xmm0, xmm0
        packuswb  xmm0, xmm0
        movd      eax, xmm0
        or        eax, 0ff000000h
    end;
    

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

        因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:maozefa@hotmail.com

        这里可访问《Delphi图像处理 -- 文章索引》。

  • 相关阅读:
    【QT】error: 'connect'/'sender' was not declared in this scope
    【QT】添加图片资源并使用QImage加载图片显示
    【QT】去掉.ui窗口的最大化、最小化和关闭按钮
    【Linux】(一)美化Linux终端之oh-my-zsh开源项目(Linux终端主题)
    【git】配置git命令行别名
    浅谈函数防抖与函数节流
    php连接数据库的天龙八部!
    JavaScript画圆
    表格的即时编辑
    用html+css+js模拟下拉菜单
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3458880.html
Copyright © 2011-2022 走看看