Programmatically determine the average greyscale

Sannyasin Brahmanathaswami brahma at
Fri Feb 19 20:14:20 CET 2016


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... 


On February 19, 2016 at 7:49:23 AM, [-hh] (hh at at 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
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:

More information about the use-livecode mailing list