News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How to make a Bitmap Gradient?

Started by AeroASM, February 21, 2005, 12:50:16 PM

Previous topic - Next topic

AeroASM

I need an algorithm which takes a value of ecx between 0 and 100, and puts a pixel into a bitmap such that:

if ecx = 0 then the pixel is black
as ecx goes from 1 to 50 the pixel goes from white to red
as ecx goes from 51 to 100 the pixel goes from red to black.

I have tried this but it didn't work too well.

donkey

There are many ways to do this, mostly it depends on how fast you want to do it. For TBPaint I was not concerned about speed so I did my gradient using floating point. You can get more speed using integer math or MMX but since my images are max 48x48 it does not significantly affect the speed. Also because TBPaint only uses 32 bit DIBs internally and addresses the pixels directly (bypassing the GDI) I use an internal BresLine routine to draw the fill lines, you can use any line drawing routine you like.

GradientFillRectDIB FRAME gBitmap,StartColor,EndColor,gradRect,gradFillMethod
uses edi,esi,ebx
LOCAL gradDIBits :D
LOCAL gbmp :DIBSECTION
LOCAL gradSteps :D
LOCAL StepColor :D

LOCAL tempDWORD :D

LOCAL FloatRed :D
LOCAL FloatGrn :D
LOCAL FloatBlu :D

LOCAL bRed1 :B
LOCAL bGreen1 :B
LOCAL bBlue1 :B

LOCAL bRed2 :B
LOCAL bGreen2 :B
LOCAL bBlue2 :B

LOCAL deltaRED :D
LOCAL deltaGRN :D
LOCAL deltaBLU :D

LOCAL rect :RECT

mov eax,[StartColor]
mov [bRed1],al
mov [bGreen1],ah
shr eax,8
mov [bBlue1],ah

mov eax,[EndColor]
mov [bRed2],al
mov [bGreen2],ah
shr eax,8
mov [bBlue2],ah

; Get the DIBits
invoke GetObjectA,[gBitmap],SIZEOF DIBSECTION,ADDR gbmp
mov eax,[gbmp.dsBm.bmBits]
mov [gradDIBits],eax

mov edi,[gradRect]

mov eax,[EDI+RECT.left]
mov [rect.left],eax
mov eax,[EDI+RECT.top]
mov [rect.top],eax
mov eax,[EDI+RECT.right]
mov [rect.right],eax
mov eax,[EDI+RECT.bottom]
mov [rect.bottom],eax

; Calulate the steps for each color
; Find the number of steps
cmp D[gradFillMethod],0 ; 0 = vert, !0 = Horiz
jne >
mov eax,[rect.bottom]
jmp >C1
:
mov eax,[rect.right]
C1:
mov [gradSteps],eax

mov eax,[rect.left]
add [rect.right],eax
mov eax,[rect.top]
add [rect.bottom],eax

; Red step
movzx eax,B[bRed1]
mov [tempDWORD],eax
fild D[tempDWORD]
fstp D[FloatRed]
movzx ecx,B[bRed2]
sub eax,ecx
neg eax
mov [deltaRED],eax
fild D[deltaRED]
fidiv D[gradSteps]
fstp D[deltaRED]

; Green step
movzx eax,B[bGreen1]
mov [tempDWORD],eax
fild D[tempDWORD]
fstp D[FloatGrn]
movzx ecx,B[bGreen2]
sub eax,ecx
neg eax
mov [deltaGRN],eax
fild D[deltaGRN]
fidiv D[gradSteps]
fstp D[deltaGRN]

; Blue step
movzx eax,B[bBlue1]
mov [tempDWORD],eax
fild D[tempDWORD]
fstp D[FloatBlu]
movzx ecx,B[bBlue2]
sub eax,ecx
or eax,eax
neg eax
mov [deltaBLU],eax
fild D[deltaBLU]
fidiv D[gradSteps]
fstp D[deltaBLU]

; Begin the fill, start at 0,0 to rect.right
mov esi,[StartColor]
xor ebx,ebx

cmp D[gradFillMethod],0
jne >>.VERT
; Horizontal fill
:
mov eax,ebx
add eax,[rect.top]
invoke BresLine,[gBitmap],[rect.left],eax,[rect.right],eax,esi

fld D[FloatRed]
fadd D[deltaRED]
fst D[FloatRed]
fistp D[tempDWORD]
mov esi,[tempDWORD]
and esi,0FFh

fld D[FloatGrn]
fadd D[deltaGRN]
fst D[FloatGrn]
fistp D[tempDWORD]
mov ecx,[tempDWORD]
and ecx,0FFh
shl ecx,8
or esi,ecx

shr eax,8
movzx ecx,al
mov [tempDWORD],ecx
fld D[FloatBlu]
fadd D[deltaBLU]
fst D[FloatBlu]
fistp D[tempDWORD]
mov ecx,[tempDWORD]
and ecx,0FFh
shl ecx,16
or esi,ecx

inc ebx
cmp ebx,[gradSteps]
jle <<
ret

.VERT
; Vertical fill
xor ebx,ebx
:
mov eax,ebx
add eax,[rect.left]
invoke BresLine,[gBitmap],eax,[rect.top],eax,[rect.bottom],esi

fld D[FloatRed]
fadd D[deltaRED]
fst D[FloatRed]
fistp D[tempDWORD]
mov esi,[tempDWORD]
and esi,0FFh

fld D[FloatGrn]
fadd D[deltaGRN]
fst D[FloatGrn]
fistp D[tempDWORD]
mov ecx,[tempDWORD]
and ecx,0FFh
shl ecx,8
or esi,ecx

shr eax,8
movzx ecx,al
mov [tempDWORD],ecx
fld D[FloatBlu]
fadd D[deltaBLU]
fst D[FloatBlu]
fistp D[tempDWORD]
mov ecx,[tempDWORD]
and ecx,0FFh
shl ecx,16
or esi,ecx

inc ebx
cmp ebx,[gradSteps]
jle <<
ret

ENDF
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable