my first attempt at using CreateDIBSection :P
it seems to work pretty well
AverageColor PROTO :HBITMAP
;***********************************************************************************************
AverageColor PROC USES EBX ESI EDI hbmpBitmap:HBITMAP
;Returns a COLORREF value that approximates the algebraic mean color of an image.
;by DednDave, 6-14-2012
;
;Call With: hbmpBitmap = bitmap image handle
;
; Returns: if successful, EAX = average image color
; EDX = contrasting color (EAX xor 808080h)
; if unsuccessful, EAX = 0 (black)
; EDX = 0FFFFFFh (white)
;
;-------------------------------
AVGCLR_SIZMAX EQU 1564000
AVGCLR_DIMSML EQU 1000
AVGCLR_DIMLRG EQU 1564
AVGCLR_DIMSQR EQU 1252
;-------------------------------
LOCAL hdcMem1 :HDC
LOCAL hdcMem2 :HDC
LOCAL hbmpMem2 :HBITMAP
LOCAL hbmpPrev1 :HBITMAP
LOCAL hbmpPrev2 :HBITMAP
LOCAL pvBits :LPVOID
LOCAL sizeBitmap :_SIZE
LOCAL uBytesPerLine :DWORD
LOCAL bmis :BITMAPINFO
;BITMAPINFO STRUCT
; bmiHeader BITMAPINFOHEADER <>
; biSize dd ? ;BITMAPINFOHEADER structure size
; biWidth dd ? ;image width in pixels
; biHeight dd ? ;signed image height in pixels
; biPlanes dw ? ;= 1
; biBitCount dw ? ;= 24
; biCompression dd ? ;= BI_RGB
; biSizeImage dd ? ;image data bytes
; biXPelsPerMeter dd ? ;= 0
; biYPelsPerMeter dd ? ;= 0
; biClrUsed dd ? ;= 0
; biClrImportant dd ? ;= 0
; bmiColors RGBQUAD <>
;-------------------------------
INVOKE GetBitmapSize,hbmpBitmap,addr sizeBitmap
mov esi,eax ;ESI = image height
xor ebx,ebx
mul ecx
mov edi,ecx ;EDI = image width
or edx,edx
jnz AvgCl1
or eax,eax
jnz AvgCl0
;the image has a width or height of 0, or both
mov edx,0FFFFFFh
jmp AvgCl9
AvgCl0: cmp eax,AVGCLR_SIZMAX
jbe AvgCl4
;If we come here, it means we are going to reduce the image.
;We divide the larger image dimension by the smaller one.
;If that ratio is greater than or equal to 1.25:1, we use a
;rectangle of AVGCLR_DIMLRG x AVGCLR_DIMSML if the image is
;wide, or AVGCLR_DIMSML x AVGCLR_DIMLRG if the image is tall.
;Otherwise, we use a square of AVGCLR_DIMSQR x AVGCLR_DIMSQR.
AvgCl1: xor edx,edx
mov eax,esi
inc ebx
cmp eax,ecx
jae AvgCl2
xchg eax,ecx
AvgCl2: div ecx
dec eax
jnz AvgCl3
shl edx,2
cmp edx,ecx
jae AvgCl3
mov edi,AVGCLR_DIMSQR
mov esi,edi
jmp short AvgCl4
AvgCl3: cmp edi,esi
mov edi,AVGCLR_DIMLRG
mov esi,AVGCLR_DIMSML
jae AvgCl4
xchg edi,esi
AvgCl4: mov eax,edi
xor edx,edx
mov bmis.bmiHeader.biSize,sizeof BITMAPINFOHEADER
shl eax,1
mov bmis.bmiHeader.biWidth,edi
mov bmis.bmiHeader.biHeight,esi
add eax,edi
mov bmis.bmiHeader.biCompression,edx ;BI_RGB = 0
mov bmis.bmiHeader.biXPelsPerMeter,edx
add eax,3
mov bmis.bmiHeader.biYPelsPerMeter,edx
and al,0FCh
mov bmis.bmiHeader.biClrUsed,edx
mov bmis.bmiHeader.biClrImportant,edx
mov uBytesPerLine,eax
mov bmis.bmiHeader.biPlanes,1
mul esi
mov bmis.bmiHeader.biBitCount,24
mov bmis.bmiHeader.biSizeImage,eax
push edi
INVOKE GetDC,HWND_DESKTOP
xchg eax,edi
INVOKE CreateCompatibleDC,edi
mov hdcMem1,eax
INVOKE SelectObject,eax,hbmpBitmap
xor edx,edx
mov hbmpPrev1,eax
INVOKE CreateDIBSection,edi,addr bmis,DIB_RGB_COLORS,addr pvBits,edx,edx
mov hbmpMem2,eax
INVOKE CreateCompatibleDC,edi
mov hdcMem2,eax
INVOKE SelectObject,eax,hbmpMem2
mov hbmpPrev2,eax
INVOKE ReleaseDC,HWND_DESKTOP,edi
dec ebx
pop edi
jz AvgCl5
inc ebx
INVOKE BitBlt,hdcMem2,ebx,ebx,edi,esi,hdcMem1,ebx,ebx,SRCCOPY
jmp short AvgCl6
AvgCl5: INVOKE SetStretchBltMode,hdcMem2,HALFTONE
INVOKE SetBrushOrgEx,hdcMem2,ebx,ebx,ebx
INVOKE StretchBlt,hdcMem2,ebx,ebx,edi,esi,hdcMem1,
ebx,ebx,sizeBitmap.x,sizeBitmap.y,SRCCOPY
;EDI = DIB section width
;ESI = DIB section height
;pvBits = address of first image scan line
;uBytesPerLine = bytes per line
AvgCl6: push ebp
push esi
mov edx,pvBits
mov eax,ebx
push uBytesPerLine
mov ecx,ebx
mov ebp,ebx
AvgCl7: push edi
push edx
AvgCl8: mov al,[edx]
add ebx,eax
mov al,[edx+1]
add ecx,eax
mov al,[edx+2]
add edx,3
add ebp,eax
sub edi,1
jnz AvgCl8
pop edx
pop edi
add edx,[esp]
sub esi,1
jnz AvgCl7
pop edx
pop eax
mul edi
xchg eax,edi
;EBX = blue total
;ECX = green total
;EBP = red total
;ESI = 0
;EDI = divisor
mov eax,ebx
mov edx,esi
mov ebx,esi
div edi
shl edx,1
cmp edx,edi
sbb al,-1
adc al,-1
mov bh,al
mov edx,esi
mov eax,ecx
shl ebx,8
div edi
shl edx,1
cmp edx,ecx
sbb al,-1
adc al,-1
mov edx,esi
mov bh,al
mov eax,ebp
div edi
shl edx,1
cmp edx,ecx
sbb al,-1
adc al,-1
mov bl,al
pop ebp
INVOKE SelectObject,hdcMem2,hbmpPrev2
INVOKE DeleteObject,eax
INVOKE DeleteDC,hdcMem2
INVOKE SelectObject,hdcMem1,hbmpPrev1
INVOKE DeleteDC,hdcMem1
xchg eax,ebx
mov edx,eax
xor edx,808080h
AvgCl9: ret
AverageColor ENDP
;***********************************************************************************************