Блюр-эффектДовольно простой эффект, как раз для начинающих. К тому же, этот эффект лежит в основе целого семейства эффектов, и знать его необходимо! Blur, в переводе с английского: неясные очертания, размытое пятно. Допустим, у нас есть некое изображение размером 320x200x8bit, в буфере экрана screen. Создаем дополнительный буфер экрана, buffer. Цвет точки с координатами X,Y в массиве buffer будет рассчитываться по формуле: цвет_точки = среднее арифметическое от значений цвета точек, окружающих точку с координатами X,Y в массиве screen. После применения данной формулы ко всем точкам массива buffer, в этом массиве будет находиться сBlur-енное изображение. Некоторые замечания: Естественно, палитра должна содержать плавные переходы от цвета к цвету, иначе вместо сBlur-енного изображения получим невесть что. Если это условие не выполняется, то надо преобразовать исходное изображение в Hi или TrueColor и производить размыв изображения отдельно для каждого цвета. При получении размытого изображения значения цвета на границах buffer не рассчитывается, иначе нам бы пришлось бы залезть за границы массива screen. Пример: Код (C): for(short y=1;y<199;y++) for(short x=1;x<319;x++) buffer[x][y]=(screen[x-1][y+1]+screen[x-1][y]+ screen[x-1][y-1]+screen[x][y+1]+ screen[x][y-1]+screen[x+1][y+1]+ screen[x+1][y]+screen[x+1][y-1])/8; В данном примере мы усредняем значение цвета 8 точек, в принципе выбор точек, по которым мы находим усредненное значение цвета, за вами. Например, для более высокой скорости можно выбрать только 4 близлежащих точки: Код (C): buffer[x][y]=(screen[x-1][y]+screen[x][y+1]+ screen[x][y-1]+screen[x+1][y])/4; Но тогда появляется неприятный побочный эффект: в местах плавных переходов цветов появляется решетка... В общем, не знаю как объяснить, попробуйте и увидите сами. Как от этого избавиться? В true блюре - никак. Но есть вариант блюра, в котором этот эффект не появляется: Код (C): screen[x][y]=(screen[x-1][y]+screen[x][y+1]+ screen[x][y-1]+screen[x+1][y])/4; Относительно true блюра имеем:Преимущества: Скорость Отпадает необходимость использования дополнительного frame-буфера. Недостаток:Искажение геометрических соотношений изображения. Обычно такой вариант Blur`a используется для улучшения качества картинки, на различных стадиях вывода изображения. Взято здесь, текст программы немного переделан, в результате СОМ-файл уменьшился с 498 байт до 408 байт. Код (ASM): ; masm dos com # .model tiny .code .686p .mmx WIDTH_SCREEN equ 320 HEIGHT_SCREEN equ 200 SCREENSIZE equ WIDTH_SCREEN*HEIGHT_SCREEN MEMBLOCKSIZE equ SCREENSIZE/16 IMPUT_STATUS_0 equ 3DAh ;регистр статуса ввода 0 VGA_SEGMENT equ 0A000h screen equ word ptr [bp-2] buffer equ word ptr [bp-4] org 100h start: mov sp,0B00h ; ADJUST MEMORY BLOCK SIZE (SETBLOCK) mov ah,4Ah ; ES = segment address of block to change mov bx,0B0h ; BX = new size in paragraphs int 21h enter 4,0 mov ax,13h int 10h ;setcolortable------------------------------- ; FOR(CL=0;CL<=63;CL++){ ; setrgbpalette(CL,CL,0,0); ; setrgbpalette(CL+64,63,CL,0); ; setrgbpalette(CL+128,63,63,CL); ; setrgbpalette(CL+192,63,63,63); mov cx,63 @@: push cx push cx push 0 push 0 call setrgbpalette mov al, cl add al,64 push ax push 63 push cx push 0 call setrgbpalette mov al,cl add al,128 push ax push 63 push 63 push cx call setrgbpalette mov al,cl add al,192 push ax push 63 push 63 push 63 call setrgbpalette dec cx jns @b ;setcolortable-------------------------------- mov bx, MEMBLOCKSIZE mov ah,48h ; ALLOCATE MEMORY int 21h ; BX = number of 16-byte paragraphs desired mov screen, ax mov bx, MEMBLOCKSIZE mov ah,48h ; ALLOCATE MEMORY int 21h ; BX = number of 16-byte paragraphs desired mov buffer, ax ;CLEARBLOCK------------------------------------------ mov es, ax xor eax, eax xor di, di mov cx,SCREENSIZE/4 rep stosd ;fillscreen------------------------------------------- mov es, screen mov di,WIDTH_SCREEN+1 mov si,HEIGHT_SCREEN-2 or ax,-1 @@: mov cx,WIDTH_SCREEN/2 - 1 rep stosw add di,2 dec si jnz @b ;trueblurscreen---------------------------------------- ; ES=screen; ; FS=buffer; ; DI=321; ; FOR(SI=1;SI<199;SI++){ ; FOR(BX=1;BX<319;BX++,DI++){ ; FSBYTE[DI]=int ESBYTE[DI-321]+ESBYTE[DI-320]+ESBYTE[DI-319]+ ; ESBYTE[DI-1]+ESBYTE[DI+1]+ESBYTE[DI+319]+ESBYTE[DI+320]+ ; ESBYTE[DI+321]>>3; a0: mov es,screen mov fs,buffer mov di, WIDTH_SCREEN+1 mov si,HEIGHT_SCREEN-2 a1: mov bx,WIDTH_SCREEN-2 @@: movzx ax, byte ptr es:[di-WIDTH_SCREEN-1] movzx cx, byte ptr es:[di-WIDTH_SCREEN] add ax, cx movzx cx, byte ptr es:[di-WIDTH_SCREEN+1] add ax, cx movzx cx, byte ptr es:[di-1] add ax, cx movzx cx, byte ptr es:[di+1] add ax, cx movzx cx, byte ptr es:[di+WIDTH_SCREEN-1] add ax, cx movzx cx, byte ptr es:[di+WIDTH_SCREEN] add ax, cx movzx cx, byte ptr es:[di+WIDTH_SCREEN+1] add ax, cx sar ax, 3 mov fs:[di], al inc di dec bx jnz @b add di,2 dec si jnz a1 ;copybufferscreen--------------------------- push ds mov ds,buffer xor di,di mov cx,SCREENSIZE/4 rep movsd pop ds call copyvirtualscreen jz a0 mov ah, 0 int 16h ; Return: AH = scan code, AL = character ;fillscreen------------------------------------------------ mov es, screen mov di,WIDTH_SCREEN+1 mov si,HEIGHT_SCREEN-2 or ax,-1 @@: mov cx,WIDTH_SCREEN/2 - 1 rep stosw add di,2 dec si jnz @b a2:;fastblurscreen ;ES=screen; ; DI=321; ; FOR(SI=1;SI<199;SI++){ ; FOR(BX=1;BX<319;BX++,DI++) ;ES:[DI]=(ES:[DI-320]+ES:[DI-1]+ES:[DI+1]+ES:[DI+320])/4 mov es,screen mov di,WIDTH_SCREEN+1 mov si,HEIGHT_SCREEN-2 a3: mov bx,WIDTH_SCREEN-2 @@: movzx ax,byte ptr es:[di-WIDTH_SCREEN] movzx cx,byte ptr es:[di-1] add ax,cx movzx cx,byte ptr es:[di+1] add ax,cx movzx cx,byte ptr es:[di+WIDTH_SCREEN] add ax,cx sar ax,2 mov es:[di], al inc di dec bx jnz @b add di,2 dec si jnz a3 ;fastblurscreen--------------------------------- call copyvirtualscreen jz a2 mov ax,3 int 10h ; - VIDEO - SET VIDEO MODE mov ah,0 int 16h ; KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTY int 20h setrgbpalette proc blue equ byte ptr [bp+4] green equ byte ptr [bp+6] red equ byte ptr [bp+8] color equ byte ptr [bp+0Ah] push bp mov bp, sp mov dx, 3C8h mov al, color mov ah, red out dx, ax inc dx mov al, green out dx, al mov al, blue out dx, al pop bp retn 8 setrgbpalette endp copyvirtualscreen proc mov dx,IMPUT_STATUS_0 WaitVerticalSync:in al,dx test al,8 jz WaitVerticalSync WaitNotVerticalSync:in al,dx test al,8 jnz WaitNotVerticalSync mov cx,SCREENSIZE/4 xor si,si push ds mov ds,screen xor di,di push VGA_SEGMENT pop es rep movsd xor ax, ax mov ds, ax mov ax, ds:[41Ah] sub ax, ds:[41Ch] pop ds retn copyvirtualscreen endp end start