zoukankan      html  css  js  c++  java
  • Delphi图像处理 -- 最大值

    阅读提示:

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

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

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

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

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

    procedure DoMaxValue(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
        pxor      mm0, mm0
        pxor      mm1, mm1
        pxor      mm2, mm2
    @@iLoop:
        push      eax
    @@jLoop:
        pmaxub    mm1, [esi]
        pmaxub    mm2, [esi+ebx]
        add       esi, 8
        dec       eax
        jnz       @@jLoop
        movd      mm3, [esi]
        movd      mm4, [esi+ebx]
        pmaxub    mm0, mm3
        pmaxub    mm0, mm4
        pop       eax
        add       esi, jOffset
        dec       edx
        jnz       @@iLoop
        push      eax
    @@jlLoop:
        pmaxub    mm1, [esi]
        add       esi, 8
        dec       eax
        jnz       @@jlLoop
        movd      mm3, [esi]
        pmaxub    mm0, mm3
        pop       eax
        pmaxub    mm0, mm1
        pmaxub    mm0, mm2
        psrlq     mm1, 32
        psrlq     mm2, 32
        pmaxub    mm0, mm1
        pmaxub    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 DoMinAlpha(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
        mov       eax, 255
    @@iLoop:
        push      edx
    @@jLoop:
        cmp       al, [esi]
        jbe       @@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 ImageMaxValue(var Data: TImageData; Radius: Integer);
    var
      src: TImageData;
    begin
      if Data.AlphaFlag then
        ArgbConvertPArgb(Data);           // 如果图像数据含Alpha信息,转换为PARGB
      src := _GetExpandData(Data, Radius);// 获取扩展半径后的图像数据源
      DoMaxValue(Data, src, Radius);      // 图像数据的最大值处理
      if Data.AlphaFlag then              // 如果图像数据含Alpha信息
      begin
        DoMinAlpha(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('....mediaapple.png');
      bmp := TGpBitmap.Create('....mediasource.bmp');
      data := LockGpBitmap(bmp);
      ImageMaxValue(data, 3);
      UnlockGpBitmap(bmp, data);
      g := TGpGraphics.Create(Canvas.Handle);
      g.DrawImage(bmp, 140, 0);
      g.Free;
      bmp.Free;
    end;
    



      

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

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

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

  • 相关阅读:
    生成缩略图时报GDI+中发生一般性错误
    跨数据库服务器查询和跨表更新
    javascript,jquery(闭包概念)
    聚集索引和非聚集索引(整理)
    ASP.NET MVC的过滤器
    如何在标题栏title前添加网站logo?
    sql语句执行顺序
    详解ASP.NET MVC的请求生命周期
    在事务中执行批量复制操作SqlBulkCopy,SqlTransaction .
    基于TCP 协议的RPC
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3194156.html
Copyright © 2011-2022 走看看