Average color function

Source-code only - please, don't post questions here.
Pitto
Posts: 68
Joined: Nov 19, 2012 19:58

Average color function

Postby Pitto » Sep 03, 2017 9:59

This functions returns the average color (arithmetic mean) of a monodimensional array of rgb values

Something like this:
Image

Code: Select all

#include "fbgfx.bi"
'Average color function:
'given an array of rgb colors values as argument
'returns the average color using the arithmetic mean
function average_color(rgb_values() as Ulong) as Ulong
   dim as integer r, g, b, c
   
   r = 0 : g = 0 : b = 0
   
   for c = 0 to Ubound(rgb_values)
      'get each r, g, b value
      r += rgb_values(c) shr 16
      g += rgb_values(c) shr 8 and &hFF
      b += rgb_values(c) and &hFF
   next c
   
   'Arithmetic mean
   r = r / (c+1)
   g = g / (c+1)
   b = b / (c+1)

   return rgb(r,g,b)

end function

dim rgb_values(0 to 7) as Ulong = {   &hDD0000, &hFF00FF, &hFF0000, &hFFDD00, _
                           &hDDFFF0, &h00DD55, &h004400, &hFF5500}
dim c as integer

screenres 320, 240, 24
draw string (20, 10), "colors palette"
'test boxes
for c = 0 to Ubound(rgb_values)
   line (c * 20 + 20,20) - step(20,20), rgb_values(c), bf
next c
draw string (120, 70), "average color"
draw string (120, 80), "of the palette"
draw string (120, 90), "(Arithmetic mean)"
line (20,60) - step(80, 80), average_color(rgb_values()), bf

sleep
Stonemonkey
Posts: 526
Joined: Jun 09, 2005 0:08

Re: Average color function

Postby Stonemonkey » Sep 03, 2017 16:17

Cool, it might be an idea to mask when adding the red components as the high byte (alpha) may not always be zero. Also if this was going to be used for some sort of processing where it's called many times, integer division is faster, \ instead of /
Muttonhead
Posts: 113
Joined: May 28, 2009 20:07

Re: Average color function

Postby Muttonhead » Sep 09, 2017 17:11

Hmmmm, look at row 17 in the code

Code: Select all

#include "fbgfx.bi"
'Average color function:
'given an array of rgb colors values as argument
'returns the average color using the arithmetic mean
function average_color(rgb_values() as Ulong) as Ulong
   dim as integer r, g, b, c
   
   r = 0 : g = 0 : b = 0
   
   for c = 0 to Ubound(rgb_values)
      'get each r, g, b value
      r += rgb_values(c) shr 16
      g += rgb_values(c) shr 8 and &hFF
      b += rgb_values(c) and &hFF
   next c
   
   print c+1'<---- its 9! your example contains 8 colors only
   'im not sure about the behavior of the "running variable" when leaving a FOR...NEXT loop
   
   'Arithmetic mean
   r = r / (c+1)
   g = g / (c+1)
   b = b / (c+1)

   return rgb(r,g,b)

end function

dim rgb_values(0 to 7) as Ulong = {   &hDD0000, &hFF00FF, &hFF0000, &hFFDD00, _
                           &hDDFFF0, &h00DD55, &h004400, &hFF5500}
dim c as integer

screenres 320, 240, 24
draw string (20, 10), "colors palette"
'test boxes
for c = 0 to Ubound(rgb_values)
   line (c * 20 + 20,20) - step(20,20), rgb_values(c), bf
next c
draw string (120, 70), "average color"
draw string (120, 80), "of the palette"
draw string (120, 90), "(Arithmetic mean)"
line (20,60) - step(80, 80), average_color(rgb_values()), bf

sleep


mutton
Pitto
Posts: 68
Joined: Nov 19, 2012 19:58

Re: Average color function

Postby Pitto » Sep 09, 2017 19:43

Hi Muttonhead,
you're right. Here's a better version.

Image

Code: Select all

#include "fbgfx.bi"
#DEFINE debug 1

'Average color function:
'given an array of rgb colors values as argument
'returns the average color using the arithmetic mean
function average_color(rgb_values() as Ulong) as Ulong
   dim as integer r, g, b, c, arraylen
   
   arraylen = UBound(rgb_values) - LBound(rgb_values) + 1
   
   r = 0 : g = 0 : b = 0
   #ifdef debug
      print "", "R-sum","G-sum","B-sum", "HEX"
   #endif
   for c = Lbound(rgb_values) to Ubound(rgb_values)
   
      'get each r, g, b value
      r += rgb_values(c) shr 16
      g += rgb_values(c) shr 8 and &hFF
      b += rgb_values(c) and &hFF
      
      #ifdef debug
         print c, r,g,b, str(hex(rgb_values(c)))
      #endif
   next c
   
   #ifdef debug
      print ""
      print "n. of elements in the array: ", arraylen
   #endif
   r = r \ (arraylen)
   g = g \ (arraylen)
   b = b \ (arraylen)

   return rgb(r,g,b)

end function

dim rgb_values(0 to 7) as Ulong = {   &hDD0000, &hFF00FF, &hFF0000, &hFFDD00, _
                           &hDDFFF0, &h00DD55, &h004400, &hFF5500}
dim c as integer

screenres 640, 480, 24
draw string (20, 10), "colors palette"
'test boxes
for c = Lbound(rgb_values) to Ubound(rgb_values)
   line (c * 30 + 20,150) - step(30,30), rgb_values(c), bf
   draw string (c * 30 + 35, 130), str(c)
next c
draw string (120, 200), "average color"
draw string (120, 210), "of the palette"
draw string (120, 220), "(Arithmetic mean)"
line (20,200) - step(80, 80), average_color(rgb_values()), bf

sleep


I didn't know that the `for…next` loop statement's iterator in FreeBasic behave like the `for` loop statement in C.
But this is yet well documented: "A For...Next loop initializes iterator to startvalue, then executes the statement block, incrementing iterator by stepvalue until it exceeds endvalue."

Thank you, I've learned a useful thing.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests