将公式化简可得:
newP=P1-(P1-P2)*(Alpha/255);
(Alpha/255)可以预先算出来作为常量带入。
要想加快速度就要减少运算的次数,特别是乘除法的次数。在化简后的算式里只有一次乘法,
而你原先的要两次乘法和一次除法。试试吧,要是还不行就得用汇编了。

解决方案 »

  1.   

    对于16b色,RGB的最大值分别是31、63、31,很不爽,要不然用MMX指令快多了。
      

  2.   

    请教MMX指令如何写?我另外再给分!100
      

  3.   

    我有一个函数,是用mmx实现把一幅图像变暗的,但你只要稍作修改就可以变为两幅图的alpha混合。
    //-----------------------------------------------------------------------------
    // Name: Alpha()
    // Desc: 实现16位图像的alpha混合.
    // -dstRect 混合区域.
    // -iDepth 图像亮度值(0 - 127).
    //-----------------------------------------------------------------------------
    void CFrameApp::Alpha(RECT dstRect,int iDepth)
    {
    int x=dstRect.left;
    int y=dstRect.top;
    int w=dstRect.right-x;
    int h=dstRect.bottom-y;
    WORD *pBitmap;
    long lPitch;
    DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    m_lpDDSBack->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
    lPitch=ddsd.lPitch;
    pBitmap = ( WORD *)((int)(ddsd.lpSurface) + y*ddsd.lPitch + x*2);
    lPitch -= (w << 1);
    //为16位565混合方式(图象大小:w x h,缓冲区指针pBitmap)
    w = w >> 2;
    _asm
    {
    mov eax,pBitmap
    mov edx,h mov ebx,07FFH ;555为03FFH
    movd mm3,ebx
    punpcklwd mm3,mm3
    punpcklwd mm3,mm3 ;绿色位遮罩07FF 07FF 07FF 07FF
    mov ebx,001FH
    movd mm4,ebx
    punpcklwd mm4,mm4
    punpcklwd mm4,mm4 ;蓝色位遮罩001F 001F 001F 001F
    movd mm5,iDepth
    punpcklwd mm5,mm5
    punpcklwd mm5,mm5 ;亮度值

    loop1: mov ecx,w
    loop2: movq mm0,[eax]
    movq mm1,mm0
    movq mm2,mm0 psrlw mm0,11 ;得到RGB单色值(R -> mm0)  555应移动10位
    pand mm1,mm3
    psrlw mm1,5 ;(G -> mm1)
    pand mm2,mm4 ;(B -> mm2) pmullw mm0,mm5 ;进行alpha合成,这里是把它变暗(*iDepth/128)
    pmullw mm1,mm5
    pmullw mm2,mm5
    psrlw mm0,7
    psrlw mm1,7
    psrlw mm2,7 psllw mm0,11 ;重新合成16位像素
    psllw mm1,5
    por mm0,mm1
    por mm0,mm2
    movq [eax],mm0 add eax,8
    dec ecx
    jnz loop2 add eax,lPitch
    dec edx
    jnz loop1
    emms
    }
    m_lpDDSBack->Unlock(NULL);
    }