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

原创 2013年12月04日 20:22:18

阅读提示:

    《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图像处理 -- 文章索引》。

 

相关文章推荐

DELPHI7的通配符比较的汇编函数

DELPHI7中的POS()函数是不能用通配符的,但是有汇编代码公开的,于是我想能否把此汇编函数改编成可能用通配符,有此想法已有多年了,最 近我重新研究这个问题,发现是可行了,并做了出来,由于时间仓...
  • aroc_lo
  • aroc_lo
  • 2010年11月20日 22:33
  • 583

delphi的万能数据库操作

好多人都抱怨delphi没有提供一个可以把任意数据放入数据库的控件,虽然说用代码实现也不难,但是有控件会更方便,这次我终于还是抽出空来做了这么个控件,以后就可以直接拖放了。它支持把任意数据类型写入数据...
  • aroc_lo
  • aroc_lo
  • 2010年01月17日 10:07
  • 833

Delphi图像处理 -- RGB与HSV转换

阅读提示:    《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。    《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。    尽可能保持...
  • maozefa
  • maozefa
  • 2013年12月04日 20:16
  • 3990

数字图像处理 颜色空间RGB、HSI、CMYK、YUV的相互转换

颜色空间也称彩色模型(又称彩色空间或彩色系统)它的用途是在某些标准下用通常可接受的方式对彩色加以说明。 本文讲解RGB与HSI、CMYK、YUV的基本概念及转换算法。...

视频图像处理基础知识5(RGB与Ycbcr相互转换公式 )

需求说明:视频处理算法基本知识       第一部分:有参考出处的RGB与Ycbcr相互转换       第二部分:简单直接的RGB与Ycbcr相互转换       第三部分:优化乘法的RG...

opencv,图像处理,rgb转换为hsv空间

图像RGB空间转换为HSV空间。  H参数表示色彩信息,即所处的光谱颜色的位置。该参数用一角度量来表示,红、绿、蓝分别相隔120度。互补色分别相差180度。  纯度S为一比例值,范围从0到1,它表...

图像处理--RGB与HSI颜色模型的转换方法介绍

最近学习一篇刘华波写的文章《RGB 与HSI 颜色模型的转换方法对比研究》,在这里记录下学习笔记 RGB颜色空间 经过详细的实验结果验证,人眼中的600~700万个锥状细胞可分...

基于mfc数字图像处理的小软件pdd-转换图片成RGB通道,反色,黑白,灰度图片

上一篇我们说到如何用MFC框架实现点击打开按钮能够打开一张图片在窗口上显示和另存为按钮能够保存到另一个文件,那么现在我们对图片进行简单的处理。 我们知道,图片是由一个一个像素组成的,我们后来会对图像...

RGB空间与HSL空间转换

  • 2013年05月13日 11:17
  • 2KB
  • 下载

HSL与RGB相互转换的Demo

  • 2011年12月19日 10:27
  • 303KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi图像处理 -- RGB与HSL转换
举报原因:
原因补充:

(最多只允许输入30个字)