Delphi影像處理 — 映像翻轉(鏡像)

來源:互聯網
上載者:User

閱讀提示:

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

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

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

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

 

    對映像的翻轉處理,是產生一個與原映像在水平方向或者垂直方向相對稱的鏡像映像。

    映像翻轉的原理很簡單,就是以映像的中間列像素(水平方向),或者中間行像素(垂直方向)為基列(行),將映像第一列(行)的像素與映像最後一列(行)的像素相交換,映像第二列(行)的像素與映像倒數第二列(行)的像素相交換......,直至基列(行)為止,如果映像的列(行)數是偶數,則頭尾對應的列(行),包括基列(行)在內兩兩交換,如果映像的列(行)數是偶數,則基列(行)不變,其它頭尾對應的列(行)兩兩交換。

    下面是映像翻轉的實現代碼:

type<br /> // 映像翻轉方式: 水平,垂直<br /> TReversalMode = (rmHorizontal, rmVertical);</p><p>流程定義:</p><p> // 翻轉映像<br /> procedure ImageReversal(var Data: TImageData; Mode: TReversalMode);</p><p>實現代碼:</p><p>procedure ImageReversal(var Data: TImageData; Mode: TReversalMode);<br />var<br /> srcOffset, dstOffset: Integer;<br />asm<br /> push esi<br /> push edi<br /> push ebx<br /> xchg eax, edx<br /> mov esi, [edx].TImageData.Scan0<br /> mov ebx, [edx].TImageData.Stride<br /> mov ecx, [edx].TImageData.Width<br /> mov edx, [edx].TImageData.Height<br /> mov srcOffset, ebx // srcOffset = Data.Stride<br /> cmp al, rmHorizontal<br /> je @@1<br /> mov edi, edx // if (Mode == rmVertical)<br /> dec edi // {<br /> imul edi, ebx // esi = Data.Scan0<br /> add edi, esi // edi = Data.Scan0 +<br /> shr edx, 1 // (Data.Height - 1) * Data.Stride<br /> neg ebx // dstOffset = -Data.Stride<br /> mov eax, 4 // edx = Data.Height / 2; eax = 4<br /> jmp @@2 // }<br /> @@1:<br /> mov edi, esi // else<br /> mov esi, ecx // {<br /> dec esi // edi = Data.Scan0<br /> shl esi, 2 // esi = Data.Scan0 + (Data.Width - 1) * 4<br /> add esi, edi // dstOffset = Data.Stride<br /> shr ecx, 1 // ecx = Data.Width / 2; eax = -4<br /> mov eax, -4 // }<br /> @@2:<br /> mov dstOffset, ebx<br /> mov ebx, eax // ebx = eax // 4 or -4<br /> cld<br /> @yLoop: // for (y = edx; y > 0; y --)<br /> push ecx // {<br /> push esi // Save(esi)<br /> push edi // Save(edi)<br /> @xLoop: // for (x = ecx; x > 0; x --)<br /> mov eax, [edi] // {<br /> xchg eax, [esi] // xchg([esi], [edi])<br /> stosd // edi += 4<br /> add esi, ebx // esi += ebx<br /> loop @xLoop // }<br /> pop edi // Reset(edi)<br /> pop esi // Reset(esi)<br /> pop ecx<br /> add esi, srcOffset // esi += srcOffset<br /> add edi, dstOffset // edi += dstOffset<br /> dec edx<br /> jnz @yLoop // }<br /> pop ebx<br /> pop edi<br /> pop esi<br />end;<br />

    下面給出一個完全等價的純PAS代碼映像翻轉過程代碼,供不太懂BASM代碼的朋友學習和使用:

procedure ImageReversal(Data: TImageData; Mode: TReversalMode);<br />var<br /> x, y: Integer;<br /> Width, Height: Integer;<br /> ps, pd, ps0, pd0: PLongWord;<br /> tmp: LongWord;<br /> Delta, dstOffset: Integer;<br />begin<br /> Width := Data.Width;<br /> Height := Data.Height;<br /> if Mode = rmHorizontal then<br /> begin<br /> pd := Data.Scan0;<br /> ps := PLongWord(Integer(pd) + (Data.Width shl 2) - 4);<br /> dstOffset := Data.Stride;<br /> Delta := -1;<br /> Width := Width shr 1;<br /> end<br /> else<br /> begin<br /> ps := Data.Scan0;<br /> pd := PLongWord(Integer(ps) + (Data.Height - 1) * Data.Stride);<br /> dstOffset := -Data.Stride;<br /> Delta := 1;<br /> Height := Height shr 1;<br /> end;<br /> for y := 1 to Height do<br /> begin<br /> pd0 := pd;<br /> ps0 := ps;<br /> for x := 1 to Width do<br /> begin<br /> tmp := pd0^;<br /> pd0^ := ps0^;<br /> ps0^ := tmp;<br /> Inc(pd0);<br /> Inc(ps0, Delta);<br /> end;<br /> Inc(Integer(ps), Data.Stride);<br /> Inc(Integer(pd), dstOffset);<br /> end;<br />end;

    下面是個映像水平翻轉的例子代碼: 

procedure TForm1.Button2Click(Sender: TObject);var  bmp: TGpBitmap;  g: TGpGraphics;  data: TImageData;begin  bmp := TGpBitmap.Create('..\..\media\001-1.jpg');  g := TGpGraphics.Create(Canvas.Handle);  g.DrawImage(bmp, 0, 0);  data := LockGpBitmap(bmp);  ImageReversal(data, rmHorizontal);  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.