程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi圖像處理 -- 最大值

Delphi圖像處理 -- 最大值

編輯: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 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('..\..\media\apple.png');   
  bmp := TGpBitmap.Create('..\..\media\source.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;  

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);
  ImageMaxValue(data, 3);
  UnlockGpBitmap(bmp, data);
  g := TGpGraphics.Create(Canvas.Handle);
  g.DrawImage(bmp, 140, 0);
  g.Free;
  bmp.Free;
end;

 

 \  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved