Fast Algorithm to Determine Average Brightness of an Image

hh hh at hyperhh.de
Wed Sep 21 05:33:41 EDT 2016


@BR

I adjusted your function a litte bit (and it works now here).
There is a new parameter for testing the upper/lower half
of the image (this param = empty tests the full image).
The mouseUp is my suggestion for a first testing. On base of
these two values you could develop a decision rule for a
dark/light setting.
[This may be better than simply averaging "sky" and "stones".
For example my first trial for a rule would be
if 0.62*upperBrightness + 0.38*lowerBrightness > 127 then
  set totalBrightnes to "light"
else set totalBrightness to "dark"]

on mouseUp
  set the paintcompression to RLE
  set topleft of img 1 to the bottomleft of me
  put the millisecs into m1
  put avgBrightness2(the long id of img 1,"upper") into b
  set backcolor of grc 1 to (b,b,b)
  put b into c
  put avgBrightness2(the long id of img 1,"lower") into b
  set backcolor of grc 2 to (b,b,b)
  put comma & b after c
  put c & ": " & (the millisecs - m1) & " ms" into fld 1
end mouseUp

## The adjusted function:

-- theImage = the long id of an img
-- thePart= "upper" or "lower" or empty (or anything else)
function avgBrightness2 theImage, thePart
  lock screen; lock messages
  put "tmp.42.42" into ii
  put the imageData of theImage into iData0
  put the width of img 1 into tOrigWidth
  if thePart is "upper" then
    put (the height of img 1) div 2 into tOrigHeight
    put byte 1 to 4*tOrigHeight*tOrigWidth of iData0 into iData0
  else if thePart is "lower" then
    put (the height of img 1) div 2 into tOrigHeight
    put byte -4*tOrigHeight*tOrigWidth to -1 of iData0 into iData0
  else
    put the height of img 1 into tOrigHeight
  end if
  repeat while there is an img ii
    delete img ii
  end repeat
  set the paintcompression to RLE -- important for speed
  create img ii
  set resizeQuality of img ii to "normal" -- "good", "best"
  set width of img ii to tOrigWidth   -- may be important*
  set height of img ii to tOrigHeight -- may be important*
  set imagedata of img ii to iData0
  put 8 into newBase -- choose newBase in range 1-64 (watch speed!)
  if tOrigWidth > tOrigHeight then
    put newBase into newHeight
    put trunc(newBase*tOrigWidth/tOrigHeight) into newWidth
  else
    put newBase into newWidth
    put trunc(newBase*tOrigHeight/tOrigWidth) into newHeight
  end if
  set width of img ii to newWidth
  set height of img ii to newHeight
  put the imagedata of img ii into iData
  delete img ii
  put 0 into vRed; put 0 into vGreen; put 0 into vBlue
  repeat with i=1 to newHeight
    put (i-1)*4 into i0
    repeat with j=1 to newWidth
      add byteToNum(byte i0+4*j-2 of iData) to vRed
      add byteToNum(byte i0+4*j-1 of iData) to vGreen
      add byteToNum(byte i0+4*j   of iData) to vBlue
    end repeat
  end repeat
  -- return round((0.1*vRed+0.6*vGreen+0.3*vBlue)/newWidth/newHeight)
  return round(avg(vRed, vGreen, vRed)/newWidth/newHeight)
  unlock screen; unlock messages
end avgBrightness2

* Your experience of "deleting" or not img "tmp" was an effect of the
resizeQuality setting because you didn't set the tmp-image to the
original's size. This differs not this much from setting the size, but
it differs by a 'jumping' amount for different original's size and
different resizeQuality.




More information about the use-livecode mailing list