Programmatically determine the average greyscale
Sannyasin Brahmanathaswami
brahma at hindu.org
Fri Feb 19 14:14:20 EST 2016
HH:
We need more "LC-mania" with a web repository for working solutions. We can find any number of Javascripts all over the place... where do we go for LC solutions like this? Have to have some kind of digger for the email lists/forums.
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"
end setLabelColor
#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
# though
on preopenCard
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)
end if
end repeat
end preopenCard
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...
BR
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
>
> =======
> Hermann
>
> 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:
> http://lists.runrev.com/mailman/listinfo/use-livecode
More information about the use-livecode
mailing list