国产毛片a精品毛-国产毛片黄片-国产毛片久久国产-国产毛片久久精品-青娱乐极品在线-青娱乐精品

16位圖像Alpha混合的實現(xiàn)

發(fā)布時間:2011-3-29 20:21    發(fā)布者:1770309616
關(guān)鍵詞: 16位圖像 , Alpha混合
Alpha 混合的算法很簡單,基于下面的公式就可以實現(xiàn):
D := A * (S - D) / 255 + D
D 是目標(biāo)圖像的像素,
S 是源圖像的像素
A 是 Alpha 值, 0 為全透明, 255 為不透明。

下面是 16 位 565 格式的混合算法的實現(xiàn),首先用最簡單的方式實現(xiàn),即逐個像素的處理:

// 一次處理一個像素,比較簡單,但速度較慢
procedure AlphaBlend656(BmpDst, BmpSrc: TBitmap; Alpha: Byte);
var
  i, j, W, H: Integer;
  pSrc, pDst: PWord;
  wSR, wSG, wSB: Word;
  wDR, wDG, wDB: Word;
begin
  // 確定高寬
  if BmpDst.Width > BmpSrc.Width then
    W := BmpSrc.Width
  else
    W := BmpDst.Width;
  if BmpDst.Height > BmpSrc.Height then
    H := BmpSrc.Height
  else
    H := BmpDst.Height;

  for i := 0 to H - 1do
  begin
    pSrc := BmpSrc.ScanLine;
    pDst := BmpDst.ScanLine;
    for j := 0 to W - 1 do
    begin
      // D := A * (S - D) / 255 + D

      wSR := (pSrc^ shr 11);
      wSG := (pSrc^ shr 5) and $3F;
      wSB := pSrc^ and $1F;

      wDR := (pDst^ shr 11);
      wDG := (pDst^ shr 5) and $3F;
      wDB := pDst^ and $1F;

      pDst^ := (((Alpha * (wSR - wDR) shr 8) + wDR) shl 11) or
               (((Alpha * (wSG - wDG) shr 8) + wDG) shl 5) or
               ((Alpha * (wSB - wDB) shr 8) + wDB);

      Inc(pSrc);
      Inc(pDst);
    end;
  end;
end;

實現(xiàn)起來很簡單,但速度比較慢,其實存在著一次處理兩個像素的算法,下面是代碼:

// 一次處理兩個像素 , 所以速度是 AlphaBlend656 的 2 倍
procedure AlphaBlend656Fast(BmpDst, BmpSrc: TBitmap; Alpha: Byte);
var
  i, j, W, H: Integer;
  pSrc, pDst: PWord;
  dwSR, dwSG, dwSB: LongWord;
  dwDR, dwDG, dwDB: LongWord;
  dwAdd64 : LongWord;
  dwAlphaOver4 : LongWord;
  odd: Boolean;
begin
    // 確定高寬
  if BmpDst.Width > BmpSrc.Width then
    W := BmpSrc.Width
  else
    W := BmpDst.Width;
  if BmpDst.Height > BmpSrc.Height then
    H := BmpSrc.Height
  else
    H := BmpDst.Height;

  dwAdd64 := 64 or ( 64 shl 16 );
  dwAlphaOver4 := ( Alpha shr 2 ) or ( ( Alpha shr 2 ) shl 16 );

  if (W and $01) = 1 then
  begin
    odd := True;
    W := (W - 1) shr 1;
  end
  else begin
    odd := False;
    W := W shr 1;
  end;

  for i := 0 to H - 1 do
  begin
    pSrc := BmpSrc.ScanLine;
    pDst := BmpDst.ScanLine;
    for j := 0 to W - 1 do
    begin
      // D := A * (S - D) / 255 + D

      dwSR := (PLongWord(pSrc)^ shr 11) and $001F001F;
      dwSG := (PLongWord(pSrc)^ shr 5) and $003F003F;
      dwSB := PLongWord(pSrc)^ and $001F001F;

      dwDR := (PLongWord(pDst)^ shr 11) and $001F001F;
      dwDG := (PLongWord(pDst)^ shr 5) and $003F003F;
      dwDB := PLongWord(pDst)^ and $001F001F;


      PLongWord(pDst)^ := ((((Alpha * (dwSR + dwAdd64 - dwDR)) shr 8) + dwDR - dwAlphaOver4) and $001F001F) shl 11 or
               ((((Alpha * (dwSG + dwAdd64 - dwDG)) shr 8) + dwDG - dwAlphaOver4 ) and $003F003F) shl 5 or
               (((Alpha * (dwSB + dwAdd64 - dwDB)) shr 8) + dwDB - dwAlphaOver4 ) and $001F001F;

      Inc(pSrc, 2);
      Inc(pDst, 2);
    end;

    if odd then
    begin
      dwSR := (pSrc^ shr 11);
      dwSG := (pSrc^ shr 5) and $3F;
      dwSB := pSrc^ and $1F;

      dwDR := (pDst^ shr 11);
      dwDG := (pDst^ shr 5) and $3F;
      dwDB := pDst^ and $1F;

      pDst^ := Word((((Alpha * (dwSR - dwDR) shr 8) + dwDR) shl 11) or
               (((Alpha * (dwSG - dwDG) shr 8) + dwDG) shl 5) or
               ((Alpha * (dwSB - dwDB) shr 8) + dwDB));

      Inc(pSrc);
      Inc(pDst);
    end;  
  end;
end;

不過這還不夠快,基本 MMX 指令的實現(xiàn)可以一次處理 4 個像素,下面是代碼:

// 利用 MMX 優(yōu)化指令,一次可以處理 4 個像素,因此速度應(yīng)該是 AlphaBlend656 的 4 倍
procedure AlphaBlend656MMX(BmpDst, BmpSrc: TBitmap; Alpha: Byte);
var
  i, j, W, H, Leave: Integer;
  pSrc, pDst: PWord;
  MaskR, MaskG, MaskB, Alpha64: Int64;
  wSR, wSG, wSB: Word;
  wDR, wDG, wDB: Word;
begin
  // 確定高寬
  if BmpDst.Width > BmpSrc.Width then
    W := BmpSrc.Width
    else
    W := BmpDst.Width;
  if BmpDst.Height > BmpSrc.Height then
    H := BmpSrc.Height
  else
    H := BmpDst.Height;

  Leave := W and 3;             // 剩余的像素
  W := W shr 2;                 // 一次處理 4 個像素,因此取 W 整除 4 的值

  // 提取 RGB 通道的掩碼
  MaskR := $f800f800f800f800;
  MaskG := $07e007e007e007e0;
  MaskB := $001f001f001f001f;

  // Alpha 值擴展到 64 位
  Alpha64 := Alpha;
  Alpha64 := Alpha64 or (Alpha64 shl 16) or (Alpha64 shl 32) or (Alpha64 shl 48);

  for i := 0 to H - 1do
  begin
    pSrc := BmpSrc.ScanLine;
    pDst := BmpDst.ScanLine;

    asm
      push    ecx               // 保存寄存器
      mov     ecx, W            // 設(shè)寬度
      cmp     ecx, 0            // 寬度是否為 0
      jz      @@exit565         // 如果寬度為 0 ,結(jié)束

      push    esi
      push    edi
      mov      esi, pSrc         // 開始處理
      mov     edi, pDst

    @@blend565_4:
    { mmx 的作用:
      mm0: red target value
      mm1: red source value
      mm2: green target value
      mm3: green source value
      mm4: blue target value
      mm5: blue source value
      mm6: original target pixel
      mm7: original source pixel

      D := A * (S - D) / 255 + D
    }
      movq    mm6, [edi]
      movq    mm7, [esi]

      movq    mm0, mm6
      pand    mm0, MaskR        // 提取目標(biāo)的 R 通道
      movq    mm1, mm7
      pand    mm1, MaskR        // 提取源的 R 通道
      psrlw   mm0, 11           // 右移到最低位,便于接下來的計算
      psrlw   mm1, 11
      psubw   mm1, mm0          // SrcRed := SrcRed - DestRed
      pmullw  mm1, Alpha64      // SrcRed := SrcRed * Alpha
      psraw   mm1, 8            // SrcRed := SrcRed div 8
      paddw   mm1, mm0          // SrcRed := SrcRed + DestRed
      psllw   mm1, 11           // 左移回原來的位置,此已經(jīng) R 通道混合已經(jīng)完畢

      movq    mm2, mm6
      pand    mm2, MaskG        // 提取目標(biāo)的 G 通道
      movq    mm3, mm7
      pand    mm3, MaskG        // 提取源的 G 通道
      psrlw   mm2, 5            // 右移到最低位,便于接下來的計算
      psrlw   mm3, 5
      psubw   mm3, mm2          // SrcGreen := SrcGreen - DestGreen
      pmullw  mm3, Alpha64      // SrcGreen := SrcGreen * Alpha
      psraw   mm3, 8            // SrcGreen := SrcGreen div 8
      paddw   mm3, mm2          // SrcGreen := SrcGreen + DestGreen
      psllw   mm3, 5            // 左移回原來的位置,此已經(jīng) G 通道混合已經(jīng)完畢

      movq    mm4, mm6
      pand    mm4, MaskB        // 提取目標(biāo)的 B 通道
      movq    mm5, mm7
      pand    mm5, MaskB        // 提取源的 B 通道
      psubw   mm5, mm4          // SrcBlue := SrcBlue - DestBlue
      pmullw  mm5, Alpha64      // SrcBlue := SrcBlue * Alpha
      psraw   mm5, 8            // SrcBlue := SrcBlue div 8
      paddw   mm5, mm4          // SrcBlue := SrcBlue + DestBlue ,此已經(jīng) B 通道混合已經(jīng)完畢

      por     mm1, mm3          // 合成像素
      por     mm1, mm5
      movq    [edi], mm1        // 賦給目標(biāo)

      add     esi, 8            // 下 4 個像素
      add     edi, 8
      dec     ecx
      jnz      @@blend565_4

      mov     pSrc, esi
      mov     pDst, edi
      pop     edi
      pop     esi
      emms

    @@exit565:
      pop     ecx
    end;

    // 處理剩下的像素
    for j := 0 to Leave - 1 do
    begin
      wSR := (pSrc^ shr 11);
      wSG := (pSrc^ shr 5) and $3F;
      wSB := pSrc^ and $1F;

      wDR := (pDst^ shr 11);
      wDG := (pDst^ shr 5) and $3F;
      wDB := pDst^ and $1F;

      pDst^ := (((Alpha * (wSR - wDR) shr 8) + wDR) shl 11) or
               (((Alpha * (wSG - wDG) shr 8) + wDG) shl 5) or
               ((Alpha * (wSB - wDB) shr 8) + wDB);

      Inc(pSrc);
      Inc(pDst);
    end;
  end;
end;

下面是這三個函數(shù)的速度比較,目標(biāo)圖像是 600*450 的 16 位位圖,源圖像是 399*532 的 16 位位圖,分別進行了 1000 次混合,結(jié)果如下:
AlphaBlend656 :           4516
AlphaBlend656Fast :       2562
AlphaBlend656MMX :        1234
沒有意外, MMX 版本比普通的快了近 4 倍

對于圖像處理的優(yōu)化有兩個比較重要的點:
1、 盡量用位移代替乘除。
2、 一次能夠同時處理多個像素,利用 MMX 指令可以做到這一點。

最后是代碼:
https://files.getdropbox.com/u/524963/AlphaBlend16_565.rar
本文地址:http://www.qingdxww.cn/thread-60397-1-1.html     【打印本頁】

本站部分文章為轉(zhuǎn)載或網(wǎng)友發(fā)布,目的在于傳遞和分享信息,并不代表本網(wǎng)贊同其觀點和對其真實性負(fù)責(zé);文章版權(quán)歸原作者及原出處所有,如涉及作品內(nèi)容、版權(quán)和其它問題,我們將根據(jù)著作權(quán)人的要求,第一時間更正或刪除。
您需要登錄后才可以發(fā)表評論 登錄 | 立即注冊

廠商推薦

  • Microchip視頻專區(qū)
  • 想要避免發(fā)生災(zāi)難,就用MPLAB SiC電源仿真器!
  • 我們是Microchip
  • 你仿真過嗎?使用免費的MPLAB Mindi模擬仿真器降低設(shè)計風(fēng)險
  • 深度體驗Microchip自動輔助駕駛應(yīng)用方案——2025巡展開啟報名!
  • 貿(mào)澤電子(Mouser)專區(qū)
關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權(quán)所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩一区二区三区在线播放 | 国产自产2023最新麻豆 | 免费韩国美女爽快一级毛片 | 四虎精品成人免费永久 | 日本不卡高清免费v日本 | 毛片91| 国产成人精品亚洲2020 | 国产精品久久久久久久久免费观看 | 99re免费视频 | 色网站观看 | 91高清在线成人免费观看 | 国产极品在线观看视频 | 91中文字幕在线一区 | 日韩欧美第一区二区三区 | 日本aaa大片 | 中文天堂最新版www在线观看 | 国产农村一一级特黄毛片 | 欧美又硬又粗又长又大 | 直接观看黄网站免费视频 | 日本一区二区三区四区视频 | 一本大道久久香蕉成人网 | 欧美日韩中文一区二区三区 | 日本卡通动漫影院网站 | 亚洲六月丁香六月婷婷花 | 免费簧片视频 | 在线观看黄色网页 | 精品一区二区在线欧美日韩 | 极品美女在线播放 | 国产精品自在在线香蕉 | 变态 调教 视频 国产九色 | 91高清完整版在线观看 | 日本在线观看免费观看完整版 | 91免费在线观看 | 日韩高清的天堂在线观看免费 | 亚洲欧美日韩高清一区二区一 | 最新一本大道香蕉综合 | 国产a v高清一区二区三区 | 国产在亚洲线视频观看 | 精品国产一区二区三区四 | 亚洲影视一区 | 欧美 另类 精品一区视频 |