Delphi图像处理 -- 最小值

阅读提示:

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

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

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

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

 

    图像的最小值处理就是以当前像素为中心,取周边一定半径范围内的所有像素的RGB分量的最小值,作为当前像素的分量值。如果图像含Alpha信息,则应对Alpha分量作一个相反的处理,即最大值处理。 

procedure DoMinValue(var Dest: TImageData; const Source: TImageData; Radius: Integer);

var

  height, iOffset, jOffset, dstOffset, srcOffset: Integer;

asm

    push      esi

    push      edi

    push      ebx

    push      ecx

    shl       ecx, 1

    mov       ebx, [edx].TImageData.Stride

    imul      ebx, ecx

    shl       ecx, 2

    add       ebx, ecx

    sub       ebx, 4

    neg       ebx

    mov       iOffset, ebx

    mov       ebx, [edx].TImageData.Stride

    push      ebx

    shl       ebx, 1

    sub       ebx, ecx

    mov       jOffset, ebx

    call      _SetCopyRegs

    mov       dstOffset, ebx

    mov       srcOffset, eax

    mov       height, edx

    pop       ebx

    pop       eax

@@yLoop:

    push      ecx

@@xLoop:

    mov       edx, eax

    pcmpeqb   mm0, mm0

    movq      mm1, mm0

    movq      mm2, mm0

@@iLoop:

    push      eax

@@jLoop:

    pminub    mm1, [esi]

    pminub    mm2, [esi+ebx]

    add       esi, 8

    dec       eax

    jnz       @@jLoop

    movd      mm3, [esi]

    movd      mm4, [esi+ebx]

    pminub    mm0, mm3

    pminub    mm0, mm4

    pop       eax

    add       esi, jOffset

    dec       edx

    jnz       @@iLoop

    push      eax

@@jlLoop:

    pminub    mm1, [esi]

    add       esi, 8

    dec       eax

    jnz       @@jlLoop

    movd      mm3, [esi]

    pminub    mm0, mm3

    pop       eax

    pminub    mm0, mm1

    pminub    mm0, mm2

    psrlq     mm1, 32

    psrlq     mm2, 32

    pminub    mm0, mm1

    pminub    mm0, mm2

    movd      [edi], mm0

    add       esi, iOffset

    add       edi, 4

    loop      @@xLoop

    pop       ecx

    add       esi, srcOffset

    add       edi, dstOffset

    dec       height

    jnz       @@yLoop

    pop       ebx

    pop       edi

    pop       esi

    emms

end;



procedure DoMaxAlpha(var Dest: TImageData; const Source: TImageData; Radius: Integer);

var

  height, iOffset, jOffset, dstOffset, srcOffset: Integer;

asm

    push      esi

    push      edi

    push      ebx

    shl       ecx, 1

    inc       ecx

    push      ecx

    mov       ebx, [edx].TImageData.Stride

    imul      ebx, ecx

    sub       ebx, 4

    neg       ebx

    mov       iOffset, ebx

    shl       ecx, 2

    mov       ebx, [edx].TImageData.Stride

    sub       ebx, ecx

    mov       jOffset, ebx

    call      _SetCopyRegs

    mov       dstOffset, ebx

    mov       srcOffset, eax

    mov       height, edx

    add       esi, 3

    add       edi, 3

    pop       edx

@@yLoop:

    push      ecx

@@xLoop:

    mov       ebx, edx

    xor       eax, eax

@@iLoop:

    push      edx

@@jLoop:

    cmp       al, [esi]

    jae       @@1

    mov       al, [esi]

@@1:

    add       esi, 4

    dec       edx

    jnz       @@jLoop

    pop       edx

    add       esi, jOffset

    dec       ebx

    jnz       @@iLoop

    mov       [edi], al

    add       esi, iOffset

    add       edi, 4

    loop      @@xLoop

    pop       ecx

    add       esi, srcOffset

    add       edi, dstOffset

    dec       height

    jnz       @@yLoop

    pop       ebx

    pop       edi

    pop       esi

end;



// 图像数据最小值处理。参数:图像数据,半径

procedure ImageMinValue(var Data: TImageData; Radius: Integer);

var

  src: TImageData;

begin

  if Data.AlphaFlag then

    ArgbConvertPArgb(Data);           // 如果图像数据含Alpha信息,转换为PARGB

  src := _GetExpandData(Data, Radius);// 获取扩展半径后的图像数据源

  DoMinValue(Data, src, Radius);      // 图像数据的最小值处理

  if Data.AlphaFlag then              // 如果图像数据含Alpha信息

  begin

    DoMaxAlpha(Data, src, Radius);    // Alpha分量作最大值处理

    PArgbConvertArgb(Data);           // 还原PARGB为ARGB

  end;

  FreeImageData(src);

end;

 

    调用例子及运行效果:

procedure TForm1.Button3Click(Sender: TObject);

var

  bmp: TGpBitmap;

  g: TGpGraphics;

  data: TImageData;

begin

//  bmp := TGpBitmap.Create('..\..\media\apple.png');

  bmp := TGpBitmap.Create('..\..\media\source.bmp');

  data := LockGpBitmap(bmp);

  ImageMinValue(data, 3);

  UnlockGpBitmap(bmp, data);

  g := TGpGraphics.Create(Canvas.Handle);

  g.DrawImage(bmp, 140, 0);

  g.Free;

  bmp.Free;

end;

Delphi图像处理 -- 最小值

Delphi图像处理 -- 最小值 

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

    因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:[email protected]

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

 

 

你可能感兴趣的:(Delphi)