Sign in to follow this  
Followers 0
anixon

Color Processing

5 posts in this topic

What I am trying to get my mind around is how to determine the color to use when embossing text on a digital image based on the digital images color at a predertimed x y location. For example if at the x y location it was say blue sky or any other light color then the embossed text would need to be black and if the location was a dark color then the embossed text would need to be white. At the moment I am drawing a box and filling the box with a light color and then embossing the box with black text. This all works fine however for appearance purposes what I want to do is get rid of the box and the color used to fill its background and simply emboss the image with text with the appropriate color so that it will display. Has anyone had a go at this or can provide some pointers?

Cheers

Ant...

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Mathematically determining the highest contrast requires some examination of the whole area you will put the text on. As an example, this function returns Avg, Min, and Max color values for a screen area:

$avColAvg = _PixelGetColorAvg(100, 100, 109, 109)
If Not @error Then
    MsgBox(64, "Results", "Results of _PixelGetColorAvg():" & @CRLF & _
    "Average color value = " & $avColAvg[0] & @CRLF & _
    "Minimum color value = " & $avColAvg[1] & @CRLF & _
    "Maximum color value = " & $avColAvg[2])
Else
    MsgBox(16, "Error", "_PixelGetColorAvg() generated @error = " & @error)
EndIf

; -------------------------------------------------
; Function:  _PixelGetColorAvg()
; Purpose:  Get average, min, and max color values of a screen area
; Call with:  _PixelGetColorAvg($x1, $y1, $x2, $y2)
; Where:  $x1, $y1 = coordinates of top/left corner
;           $x2, $y2 = coordinates of bottom/right corner
; Returns:  On success, returns an array of 24-bit RGB color values:
;       [0] = Average color value
;       [1] = Minimum color value
;       [2] = Maximum color value
;   On failure, returns -1 and sets @error
; Notes:  8-bit R, G, and B color values are separately calculated and then 
;   assembled into 24-bit results.
; -------------------------------------------------
Func _PixelGetColorAvg($x1, $y1, $x2, $y2)
    If $x2 < $x1 Or $y2 < $y1 Then Return SetError(1, 0, -1) ; Invalid parameters
    Local $x, $y, $Points = 0, $Color
    Local $Red, $Green, $Blue
    Local $RedAvg = 0, $GreenAvg = 0, $BlueAvg = 0
    Local $RedMin = 255, $GreenMin = 255, $BlueMin = 255
    Local $RedMax = 0, $GreenMax = 0, $BlueMax = 0
    
    ; Loop through the box
    For $y = $y1 To $y2
        For $x = $x1 To $x2
            $Color = PixelGetColor($x, $y)
            If $Color <> -1 Then
                ; Count the valid points used
                $Points += 1
                
                ; Get blue values
                $Blue = Mod($Color, 256)
                If $Blue < $BlueMin Then $BlueMin = $Blue
                If $Blue > $BlueMax Then $BlueMax = $Blue
                $BlueAvg += $Blue
                
                ; Get green values
                $Color = ($Color - $Blue) / 256
                $Green = Mod($Color, 256)
                If $Green < $GreenMin Then $GreenMin = $Green
                If $Green > $GreenMax Then $GreenMax = $Green
                $GreenAvg += $Green
                
                ; Get red values
                $Red = ($Color - $Green) / 256
                If $Red < $RedMin Then $RedMin = $Red
                If $Red > $RedMax Then $RedMax = $Red
                $RedAvg += $Red
            EndIf
        Next
    Next
    
    ; Test for any valid points found
    If $Points > 0 Then
        ; Calculate averages
        $RedAvg = Int($RedAvg / $Points)
        $GreenAvg = Int($GreenAvg / $Points)
        $BlueAvg = Int($BlueAvg / $Points)
        
        ; Generate 24-bit color values
        Local $ColorAvg = ((($RedAvg * 256) + $GreenAvg) * 256) + $BlueAvg
        Local $ColorMin = ((($RedMin * 256) + $GreenMin) * 256) + $BlueMin
        Local $ColorMax = ((($RedMax * 256) + $GreenMax) * 256) + $BlueMax
        
        ; Generate and return array
        Local $avRET[3] = [$ColorAvg, $ColorMin, $ColorMax]
        Return $avRET
    Else
        ; No valid point found
        Return SetError(2, 0, -1)
    EndIf
EndFunc   ;==>_PixelGetColorAvg

:)

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Here: ColourUnderMouse and look how it determines whether or not to change the text colour.

Wow aint that clever

Ant...

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Mathematically determining the highest contrast requires some examination of the whole area you will put the text on. As an example, this function returns Avg, Min, and Max color values for a screen area:

$avColAvg = _PixelGetColorAvg(100, 100, 109, 109)
If Not @error Then
    MsgBox(64, "Results", "Results of _PixelGetColorAvg():" & @CRLF & _
    "Average color value = " & $avColAvg[0] & @CRLF & _
    "Minimum color value = " & $avColAvg[1] & @CRLF & _
    "Maximum color value = " & $avColAvg[2])
Else
    MsgBox(16, "Error", "_PixelGetColorAvg() generated @error = " & @error)
EndIf

; -------------------------------------------------
; Function:  _PixelGetColorAvg()
; Purpose:  Get average, min, and max color values of a screen area
; Call with:  _PixelGetColorAvg($x1, $y1, $x2, $y2)
; Where:  $x1, $y1 = coordinates of top/left corner
;           $x2, $y2 = coordinates of bottom/right corner
; Returns:  On success, returns an array of 24-bit RGB color values:
;       [0] = Average color value
;       [1] = Minimum color value
;       [2] = Maximum color value
;   On failure, returns -1 and sets @error
; Notes:  8-bit R, G, and B color values are separately calculated and then 
;   assembled into 24-bit results.
; -------------------------------------------------
Func _PixelGetColorAvg($x1, $y1, $x2, $y2)
    If $x2 < $x1 Or $y2 < $y1 Then Return SetError(1, 0, -1) ; Invalid parameters
    Local $x, $y, $Points = 0, $Color
    Local $Red, $Green, $Blue
    Local $RedAvg = 0, $GreenAvg = 0, $BlueAvg = 0
    Local $RedMin = 255, $GreenMin = 255, $BlueMin = 255
    Local $RedMax = 0, $GreenMax = 0, $BlueMax = 0
    
    ; Loop through the box
    For $y = $y1 To $y2
        For $x = $x1 To $x2
            $Color = PixelGetColor($x, $y)
            If $Color <> -1 Then
                ; Count the valid points used
                $Points += 1
                
                ; Get blue values
                $Blue = Mod($Color, 256)
                If $Blue < $BlueMin Then $BlueMin = $Blue
                If $Blue > $BlueMax Then $BlueMax = $Blue
                $BlueAvg += $Blue
                
                ; Get green values
                $Color = ($Color - $Blue) / 256
                $Green = Mod($Color, 256)
                If $Green < $GreenMin Then $GreenMin = $Green
                If $Green > $GreenMax Then $GreenMax = $Green
                $GreenAvg += $Green
                
                ; Get red values
                $Red = ($Color - $Green) / 256
                If $Red < $RedMin Then $RedMin = $Red
                If $Red > $RedMax Then $RedMax = $Red
                $RedAvg += $Red
            EndIf
        Next
    Next
    
    ; Test for any valid points found
    If $Points > 0 Then
        ; Calculate averages
        $RedAvg = Int($RedAvg / $Points)
        $GreenAvg = Int($GreenAvg / $Points)
        $BlueAvg = Int($BlueAvg / $Points)
        
        ; Generate 24-bit color values
        Local $ColorAvg = ((($RedAvg * 256) + $GreenAvg) * 256) + $BlueAvg
        Local $ColorMin = ((($RedMin * 256) + $GreenMin) * 256) + $BlueMin
        Local $ColorMax = ((($RedMax * 256) + $GreenMax) * 256) + $BlueMax
        
        ; Generate and return array
        Local $avRET[3] = [$ColorAvg, $ColorMin, $ColorMax]
        Return $avRET
    Else
        ; No valid point found
        Return SetError(2, 0, -1)
    EndIf
EndFunc   ;==>_PixelGetColorAvg

:)

Beautiful thanks for the code very much appreciated and of course the prompt response was terrific

Ant..

Edit:

I started testing using Paint to change the color (solid) - White produced a value of 16777215 and Black a value 0 (Zero) The equivalent of Blue Sky 14286847.

On that basis for a low value the text would be white and for a high value the text would be black. The value that determines when the text should be

change from black to white is probably a bit of a guess. Actual photo images produced similar results I guess that the size and location of the color sample would

need to be determined. Will now have to go and have a look at a good number of images to form a view about where to sample.

End of Edit

Edited by anixon

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0