Programmatically determine the average greyscale
brahma at hindu.org
Fri Feb 19 20:14:20 CET 2016
Meanwhile I cooked up my own luminance checker/foregroundcolor setter, or rather cobbled together input from our friends of course...This is about as optimized as I think we are going to get. function is only 11 lines, calling handler only 10 lines.
Challenge: try and write this in 21 lines in any other language!
Stack script has this two functions
# thanks Scott and Jacque!
function setLabelColor pImage,pX,pY
put the imageData of img id pImage into theImageData
put width of img id pImage into W
put ((pY-1)*W)*4+pX*4 into lastChar
-- wikipedia luminance levels: Y = 0.2126 R + 0.7152 G + 0.0722 B
put ( charToNum(char lastChar of theImageData) ) * 0.0722 into tB
put (charToNum(char lastChar-1 of theImageData) ) * 0.7152 into tG
put ( charToNum(char lastChar-2 of theImageData) ) * 0.2126 into tR
put sum(tR,tG,tB) into tColorLevel
if tColorLevel > 170 then return "85,85,85" -- "black"
else return "white"
#Card script has this preopencard handler
#button label is set to run in the upper left area
# of the image(s) so I target a pixel that is at 40,40
# and if it is too light, then we switch to a darker color -black
updateAllButtonImages # changes all button patterns dynamically
repeat with x = 1 to the number of btns of group "sections"
put the id of btn x of group "sections" into tNextButton
put the backgroundpattern of button id tNextButton into tPatternID
if tPatternID <> empty then
set the textcolor of btn id tNextButton to setLabelColor (tPatternID,40,40)
It works. If we wanted more mania we could even start checking hues and setting the button name/label to match, bad design for this context, but something doable and possibly useful elsewhere...
On February 19, 2016 at 7:49:23 AM, [-hh] (hh at livecode.org(mailto:hh at livecode.org)) wrote:
> BR and jacques,
> it's kind of a 'LC-mania' of me to put a fully working
> solution, if available, near the end of a thread.
> Here's one I made for converting to grayLevel colours and
> adapted to your case. Tell us your solution also, please.
> The following is pretty fast, I wrote it after learning some
> secrets of imageData from Bernd's "little stacks" and forum
> posts. So praise him and LC's pointer arithmetic for the speed.
> It takes here on a medium fast machine in average 16 ms for
> your 20x20 px image segment
> (incl. setting of the button's or field's adjusted textcolor)
> local ii="preview", bb= "bigBen" -- image's and button's name
> ## Function computes an average RGB-colour value for an image
> ## (or a rectangular segment of it).
> ## Divide below in each loop if image is *very* large
> -- x = imageData 32bit ARGB of the full img ii
> -- w = width of the full image ii
> -- pixel rows = r1 to r1, pixel cols = c1 to c2
> -- wr, wg, wb = weights for r, g, b
> function weightedColorMean x,w,r1,r2,c1,c2,wr,wg,wb
> repeat with j=r1 to r2
> put (j-1)*w into j0
> repeat with i=c1 to c2
> add sum( \
> wr*byteToNum(byte 4*(j0+i)-2 of x), \
> wg*byteToNum(byte 4*(j0+i)-1 of x), \
> wb*byteToNum(byte 4*(j0+i) of x) ) to s
> end repeat
> end repeat
> return s div (sum(wr,wg,wb)*(r2-r1+1)*(c2-c1+1))
> end weightedColorMean
> on mouseUp
> put the millisecs into m1
> put the width of img ii into w
> put the imageData of img ii into iData
> -- perception values:
> put weightedColorMean(iData,w,20,40,20,40,1,6,3) into M
> -- usual luminance formula (wikipedia, cited by Jaques)
> -- put weightedColorMean(iData,w,20,40,20,40,3,10,1) into M
> if M > 191 then set textcolor of btn bb to "51,51,51"
> else set textcolor of btn bb to "255,255,225"
> put M && the millisecs-m1 && "ms" into fld 1
> end mouseUp
> p.s. Jacques: There is no semicolon above in that post ;-)
> use-livecode mailing list
> use-livecode at lists.runrev.com
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
More information about the use-livecode