Hello
You may try the AppleScript script listed below. It is a simple wrapper of rubycocoa script which uses CIFilter to calculate average brightness and hue of each image (jpg|jpeg|png) in specified directory tree. It is a skeleton just to generate a TSV output of [brightness, hue, file] records sorted by brightness and then hue on desktop. I don't know how to embed these info into image metabata.
Script is briefly tested under 10.6.8.
Hope this may help somehow,
H
PS. If copied code has extra spaces in front of every line, which appears to be the case with some browsers including Firefox, please remove them before running the script.
-- SCRIPT
set d to (choose folder with prompt "Choose start folder")
set args to d's POSIX path's quoted form
do shell script "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w <<'EOF' - " & args & " > ~/desktop/test_out.txt
#
# get average brightness and hue of image files (jpg|jpeg|png)
#
# * output record = B=brightness [TAB] H=hue [TAB] file [LF]
# * sorted by brightness and then hue
#
require 'osx/cocoa'
include OSX
EXTS = %w[ jpg jpeg png ] # target extensions
module OSX
class << CIContext
def contextWithSize(w, h)
br = NSBitmapImageRep.alloc.objc_send(
:initWithBitmapDataPlanes, nil,
:pixelsWide, w,
:pixelsHigh, h,
:bitsPerSample, 8,
:samplesPerPixel, 4,
:hasAlpha, true,
:isPlanar, false,
:colorSpaceName, NSCalibratedRGBColorSpace,
:bytesPerRow, 0,
:bitsPerPixel, 0)
c = NSGraphicsContext.graphicsContextWithBitmapImageRep(br)
CIContext.objc_send(:contextWithCGContext, c.graphicsPort , :options, {})
end
end
class CIFilter
def setParameters(dict)
self.setValuesForKeysWithDictionary(dict)
end
def output
self.valueForKey('outputImage')
end
end
class << CIVector
def vectorWithRect(r)
self.vectorWithX_Y_Z_W(r.origin.x, r.origin.y, r.size.width, r.size.height)
end
end
end
# process ARGV and retrieve image files with given extensions under specfied directory
raise ArgumentError, %Q[Usage: #{File.basename($0)} directory] unless ARGV.length == 1
dir, = ARGV.map { |a| a == '/' ? a : a.chomp('/')}
ff = %x[find -E \"#{dir}\" -type f -iregex '.*/.*\\.(#{EXTS.join('|')})$' -print0].split(/\\0/)
# get CIContext and CIFilter
cic = CIContext.contextWithSize(5000, 5000) # let it be large enough
cif = CIFilter.filterWithName('CIAreaAverage')
cif.setDefaults
# retrieve average brightness and hue of images
hh = {}
ff.each do |f|
u = NSURL.fileURLWithPath(f)
ci = CIImage.imageWithContentsOfURL(u)
civ = CIVector.vectorWithRect(ci.extent)
cif.setParameters({'inputImage' => ci, 'inputExtent' => civ})
ciout = cif.output
cgout = cic.objc_send(:createCGImage, ciout, :fromRect, ciout.extent)
colr = NSBitmapImageRep.alloc.initWithCGImage(cgout).colorAtX_y(0, 0)
hh[f] = { :b => colr.brightnessComponent, :h => colr.hueComponent}
end
# sort criteria
brightness = lambda { |k| hh[k][:b] }
hue = lambda { |k| hh[k][:h] }
brightness_and_hue = lambda { |k| b, h = hh[k].values_at(:b, :h); b * 1e6 + h }
# print sorted records
hh.keys.sort_by(&brightness_and_hue).each do |k|
b, h = hh[k].values_at(:b, :h)
puts %Q[B=%f\\tH=%f\\t%s] % [b, h, k]
end
EOF"
-- END OF SCRIPT