Сообщений 7 Оценка 75 Оценить |
Пример работы функции
Исходный текст функции - 669 b
Демонстрационная программа - 146 Kb
Итак, речь пойдет о функции, реализующей микширование двух изображений с учетом альфа-канала. Данная проблема встала передо мной поскольку моя текущая работа плотно связана с программированием графики, и, в частности, с цифровой обработкой изображений.
Windows GDI, как известно, предоставляет очень скудный инструментарий в этом плане, что приводит к необходимости самостоятельно реализовывать требуемую функциональность (опускаю обсуждение GDI+ - хорошо, но поздновато :). Надеюсь, что программистам со схожей спецификой работы, эта информация не покажется безынтересной.
void RasterAlphaBlend(int w1, int h1, int w2, int h2, DWORD* pSrc1, DWORD* pSrc2); |
w1 | ширина первого буфера, в пикселах |
---|---|
h1 | высота первого буфера, в пикселах |
w2 | ширина второго буфера, в пикселах |
h2 | высота второго буфера, в пикселах |
pSrc1 | указатель на первый буфер |
pSrc2 | указатель на второй буфер |
Исходный текст:
void RasterAlphaBlend(int w1, int h1, int w2, int h2, DWORD* pSrc1, DWORD* pSrc2) { // first source buffer (destination) must be LARGER than second!!! if (w1 < w2 || h1 < h2) return; DWORD dx1 = w1 * 4; DWORD dx2 = w2 * 4; DWORD diff = (w1 - w2) * 4; _asm{ mov esi, pSrc1 mov edi, pSrc2 mov eax, 1 cpuid test edx, 0x00800000 jz END MMX: mov ecx, h2 LM1: push ecx mov ecx, w2 LM2: mov al, [edi + 3] or al, al jz NX1 mov ah, al mov dx, ax bswap eax mov ax, dx pxor mm2, mm2 movd mm3, eax punpcklbw mm3, mm2 // a mov eax, 0xffffffff movd mm4, eax punpcklbw mm4, mm2 psubw mm4, mm3 // 1-a movd mm0, [esi] punpcklbw mm0, mm2 movd mm1, [edi] punpcklbw mm1, mm2 pmullw mm1, mm3 pmullw mm0, mm4 paddusw mm1, mm0 psrlw mm1, 8 // !!!!!!! packuswb mm1, mm2 movd ebx, mm1 and ebx, 0x00ffffff mov eax, [esi] Строка 1 and eax, 0xff000000 or eax, ebx mov [esi], eax Строка 2 NX1: add esi, 4 add edi, 4 sub ecx, 1 jnz LM2 add esi, diff pop ecx sub ecx, 1 jnz LM1 emms END: } } |
Для того, чтобы использовать функцию, необходимо:
Результат микширования будет находиться в pSrc1. Для приведенной выше реализации альфа-каналом выходного изображения будет являться альфа-канал из pSrc1.
Если в Строка 1 [esi] заменить на [edi], то результирующий альфа-канал будет взят из pSrc2.
Если же код, между Строка 1 и Строка 2, заменить на:
mov eax, [esi] and eax, 0xff000000 mov edx, [edi] and edx, 0xff000000 cmp eax, edx jnc NX2 mov eax, edx NX2: or eax, ebx mov [esi], eax |
то результирующий альфа-канал - большее из pSrc1[i] и pSrc2[i].
ПРЕДУПРЕЖДЕНИЕ Функция чувствительна к параметрам!
|
Сообщений 7 Оценка 75 Оценить |