Delphi影像處理 — 設定映像關鍵顏色

來源:互聯網
上載者:User

閱讀提示:

    《Delphi影像處理》系列以效率為側重點,一般代碼為PASCAL,核心代碼採用BASM。

    《C++影像處理》系列以代碼清晰,可讀性為主,全部使用C++代碼。

    儘可能保持二者內容一致,可相互對照。

   本文代碼必須包括文章《Delphi影像處理 -- 資料類型及公用過程》中的ImageData.pas單元。

 

    設定映像關鍵顏色,使映像的某種或某個範圍的顏色成為透明色,是圖片合成、動畫顯示中經常用的影像處理手段。下面是實現代碼:

 

procedure ColorKeyEQ;asm    punpckldq mm2, mm2      // mm2 = ColorKey  ColorKey    mov       eax, ecx    shr       ecx, 1        // 每次比較2個像素@@yLoop:    push      ecx@@xLoop:    dec       ecx    js        @@1    movq      mm0, [edi]    // mm0 = A1 R1 G1 B1 A0 R0 G0 B0    pcmpeqd   mm0, mm2      // 按32位元對2個像素進行比較    pandn     mm0, [edi]    // 比較結果取非後同原象素值作與運算    movq      [edi], mm0    // 存入結果    add       edi, 8    jmp       @@xLoop@@1:    test      eax, 1        // 比較可能存在的最後一個像素    jz        @@2    movd      mm0, [edi]    pcmpeqd   mm0, mm2    movd      ecx, mm0    not       ecx    and       [edi], ecx    add       edi, 4@@2:    pop       ecx    add       edi, ebx    dec       edx    jnz       @@yLoopend;procedure ColorKeyArea;asm    pxor      mm7, mm7      // 比較命令是按有符號數進行的,因此    punpcklbw mm2, mm7      //   ColorLow按位元組擴充為字    punpcklbw mm3, mm7      //   ColorHigh按位元組擴充為字@@yLoop:    push      ecx@@xLoop:    movd      mm0, [edi]    // mm0 = 00 00 00 00  A  R  G  B    punpcklbw mm0, mm7      // mm0 = 00  A 00  R 00  G 00  B    movq      mm1, mm2    pcmpgtw   mm1, mm0      // 比較 ColorLow 是否大於 mm0    packsswb  mm1, mm1      // 比較結果按字壓縮為位元組    movd      eax, mm1    test      eax, eax    jnz       @@Next        // 如果 ColorLow 小於等於 mm0    pcmpgtw   mm0, mm3      //   比較 mm0 是否大於 ColorHigh    packsswb  mm0, mm0      //   比較結果按字壓縮為位元組    movd      eax, mm0    test      eax, eax    jnz       @@Next        // if (argb < ColorLow || argb > ColorLor)    and       [edi], eax    //   *(int* )edi = 0@@Next:    add       edi, 4    loop      @@xLoop    pop       ecx    add       edi, ebx    dec       edx    jnz       @@yLoopend;// 設定色鍵(透明範圍)。colorLow 低色索引值; colorHigh 高色索引值// 當像素A、R、G、B值同時大於等於colorLow和小於等於colorHigh時為透明色procedure ImageSetColorKey(var Data: TImageData; ColorLow, ColorHigh: LongWord);asm    push      edi    push      ebx    movd      mm2, edx    movd      mm3, ecx    xor       edx, ecx    push      edx    call      _SetDataRegs    pop       eax    test      eax, eax    jz        @@1    call      ColorKeyArea    jmp       @@Exit@@1:    call      ColorKeyEQ@@Exit:    emms    pop       ebx    pop       ediend;// 按座標顏色設定色鍵。x,y 映像座標點, Precision 色鍵容差procedure ImageSetColorKeyPoint(var Data: TImageData; x, y: Integer; Precision: LongWord);asm    push      edi    push      ebx    test      edx, edx    js        @@Exit    cmp       edx, [eax].TImageData.Width    jae       @@Exit    test      ecx, ecx    js        @@Exit    cmp       ecx, [eax].TImageData.Height    jae       @@Exit  imul    ecx, [eax].TImageData.Stride    shl    edx, 2          // edx = data->Scan0 +  add    edx, ecx        //   y * data->Stride + x * 4  add    edx, [eax].TImageData.Scan0    pxor    mm7, mm7    movd    mm0, precision// mm0 = precision (4 word)    punpcklwd mm0, mm0    punpcklwd mm0, mm0    movd  mm2, [edx]      // mm2 = mm3 = argb (byte --> word)    punpcklbwmm2, mm7    movq    mm3, mm2    paddswmm3, mm0    // mm3 += mm0 (colorHigh)    psubswmm2, mm0    // mm2 -= mm0 (colorLow)    packuswbmm3, mm3    packuswbmm2, mm2    call      _SetDataRegs    movq      mm0, mm2    pxor      mm0, mm3    movd      eax, mm0    test      eax, eax    jz        @@2    call      ColorKeyArea    jmp       @@end@@2:    call      ColorKeyEQ@@end:    emms@@Exit:    pop       ebx    pop       ediend;

 

    上面的代碼中,提供了2種設定映像關鍵顏色過程:

    ImageSetColorKey過程,設定映像的關鍵色彩範圍,ColorLow和ColorHigh分別為映像關鍵顏色的低色索引值和高色索引值,只要是處於高低色鍵範圍內的顏色都會成為透明色,如果ColorLow與ColorHigh相等,只有一種顏色成為透明色。

    ImageSetColorKeyPoint過程,是通過映像的位置和顏色容差來設定關鍵顏色的。因為很多映像的背景色都不是單純的某種顏色,靠ImageSetColorKey過程也不好確定關鍵顏色的高低色鍵,這時可以給定一個映像座標,以這個座標位置的像素顏色為基準,凡是在基準顏色上下容差範圍內的顏色都會成為透明色。

    下面是個簡單的調用例子:

procedure TForm1.Button3Click(Sender: TObject);var  bmp: TGpBitmap;  g: TGpGraphics;  data: TImageData;begin  bmp := TGpBitmap.Create('..\media\56-3.jpg');  g := TGpGraphics.Create(Canvas.Handle);  g.DrawImage(bmp, 0, 0);  data := LockGpBitmap(bmp);  ImageSetColorKeyPoint(data, 175, 5, 39);  UnlockGpBitmap(bmp, data);  g.DrawImage(bmp, data.Width, 0);  g.Free;  bmp.Free;end;

    下面是運行效果:

 

    《Delphi影像處理》系列使用GDI+單元和說明見文章《GDI+ for VCL基礎 -- GDI+ 與 VCL》。

    因水平有限,錯誤在所難免,歡迎指正和指導。郵箱地址:maozefa@hotmail.com

    這裡可訪問《Delphi影像處理 -- 文章索引》。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.