本帖最后由 Soyokaze 于 2010-07-21 12:02:37 编辑

解决方案 »

  1.   

    >> 8
    这个是除以256
      

  2.   

    分别用两种方法生成了一个 WS_EX_LAYERED 风格的窗口,然后置于相同的背景中。接着分别在同一位置取色进行对比,可见差别并不大。移位方法的图:
    除以255的图:
      

  3.   

    Soyokaze 
    如果你不是 做专业的图像处理软件,而是在自己的界面上使用图像特效,这样做是可以的。基本上两者在视觉上无多大的差距。
      

  4.   

    移位运算效率确实高于除法运算,而且两者相差不大,不是高精度可以考虑,不过高倍加速还是建议MMX/SSE
      

  5.   

    我用内嵌汇编用MMX实现了一下,和用一般方法实现的对比了一下,发现速度不但没有提高,反倒减慢了,郁闷+不得其解中...下面是两种方法的程序段,大家给帮着看看问题出在哪里(IDE用的PureBaic):
    Structure Pixel32
        b.a
        g.a
        r.a
        a.a
    EndStructure
    *pBase = DrawingBuffer()
    cbPerLine.l = DrawingBufferPitch()
    *pPixel = *pBase
    lPixel.l
    *pixel32.Pixel32 = @lPixel
    For j = 1 To szBmp\cy
        For i = 1 To szBmp\cx
            lPixel = PeekL(*pPixel)
            *pixel32\b = (*pixel32\b * *pixel32\a) >> 8
            *pixel32\g = (*pixel32\g * *pixel32\a) >> 8
            *pixel32\r = (*pixel32\r * *pixel32\a) >> 8
            PokeL(*pPixel, lPixel)
            *pPixel + 4
        Next i
        *pPixel = *pBase + cbPerLine * j
    Next j
    PXOR      mm7, mm7     ;清零
    MOV       eax, $00ffffff
    MOVD      mm6, eax
    MOV       eax, $ff000000
    MOVD      mm5, eax
    MOV       ecx, szBmp\cy
    MOV       j, ecx
    MOV       eax, 1
    EntryY:
    MOV       ecx, szBmp\cx
    MOV       i, ecx
    EntryX:
    MOV       ecx, *pPixel
    MOVD      mm0, [ecx]   ;取像素
    MOVQ      mm2, mm0
    PUNPCKLBW mm0, mm7     ;拆为 0A 0R 0G 0B(每字符代表1个字节,后同)
    MOVQ      mm1, mm0
    PUNPCKHWD mm1, mm1     ;拆为 0A 0A 0R 0R
    PUNPCKHDQ mm1, mm1     ;拆为 0A 0A 0A 0A
    PMULLW    mm0, mm1
    PSRLW     mm0, 8
    PACKUSWB  mm0, mm7
    PAND      mm0, mm6
    PAND      mm2, mm5
    POR       mm0, mm2
    MOVD      [ecx], mm0   ;放回
    ADD       *pPixel, 4
    DEC       i
    JNZ       l_entryx     ;x循环截止
    MOV       ecx, eax     ;保存(不能压栈)
    MUL       cbPerLine
    ADD       eax, *pBase
    MOV       *pPixel, eax ;下一行首地址
    MOV       eax, ecx
    INC       eax
    DEC       j
    JNZ       l_entryy     ;y循环截止
    EMMS
      

  6.   

    编译器再怎么优化也不可能会去调用MMX的啊
      

  7.   

    __asm
    {
    PXOR      MM7,MM7 //MM7=0
    MOVD      MM0,[esi] //MM0=src;
    MOVD      MM2,[edi] //MM2=dst;
    PUNPCKLBW MM0,MM7 //MM0转QWORD AABBGGRR->00AA00BB00GG00RR
    PUNPCKLBW MM2,MM7 //MM2转QWORD AABBGGRR->00AA00BB00GG00RR
    MOVQ      MM1,MM0 //MM1=MM0
    PUNPCKHWD MM1,MM1 //MM1 00AA00BB00GG00RR->00AA00AA00CC00CC
    PUNPCKHDQ MM1,MM1 //MM1 00AA00AA00CC00CC->00AA00AA00AA00AA
    PSUBW     MM0,MM2 //MM0 -= MM2
    PSLLW     MM2,8   //MM2右移8位 00AA00BB00GG00RR->AA00BB00GG00RR00
    PMULLW    MM0,MM1 //MM0 *= MM1
    PADDW     MM2,MM0 //MM2 += MM0
    PSRLW     MM2,8   //MM2以Word为单位右移8位 AA??BB??GG??RR??->00AA00BB00GG00RR
    PACKUSWB  MM2,MM7 //MM2转DWORD 00AA00BB00GG00RR->AABBGGRR
    MOVD      [edi],MM2
    }
      

  8.   

    这段代码实现的是Alpha混合:
    Dst.Red = Src.Red * (Src.Alpha/255.0) + Dst.Red * (1.0 - (Src.Alpha/255.0))
    Dst.Green = Src.Green * (Src.Alpha/255.0) + Dst.Green * (1.0 - (Src.Alpha/255.0))
    Dst.Blue = Src.Blue * (Src.Alpha/255.0) + Dst.Blue * (1.0 - (Src.Alpha/255.0))
    而不是我要的预乘:
    Src.Red   = Src.Red   * Src.Alpha / 255
    Src.Green = Src.Green * Src.Alpha / 255
    Src.Blue  = Src.Blue  * Src.Alpha / 255
    不过还是谢谢,可以触类旁通。