photo-utils 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +4 -0
  4. data/README.rdoc +1 -0
  5. data/Rakefile +1 -0
  6. data/TODO.txt +34 -0
  7. data/bin/photo-util +39 -0
  8. data/lib/photo_utils.rb +28 -0
  9. data/lib/photo_utils/angle.rb +17 -0
  10. data/lib/photo_utils/aperture.rb +62 -0
  11. data/lib/photo_utils/apex.rb +210 -0
  12. data/lib/photo_utils/brightness.rb +49 -0
  13. data/lib/photo_utils/camera.rb +82 -0
  14. data/lib/photo_utils/compensation.rb +29 -0
  15. data/lib/photo_utils/extensions/array.rb +11 -0
  16. data/lib/photo_utils/extensions/float.rb +18 -0
  17. data/lib/photo_utils/extensions/math.rb +11 -0
  18. data/lib/photo_utils/extensions/numeric.rb +23 -0
  19. data/lib/photo_utils/formats.rb +146 -0
  20. data/lib/photo_utils/frame.rb +36 -0
  21. data/lib/photo_utils/illuminance.rb +48 -0
  22. data/lib/photo_utils/length.rb +92 -0
  23. data/lib/photo_utils/lens.rb +50 -0
  24. data/lib/photo_utils/scene.rb +180 -0
  25. data/lib/photo_utils/scene_view.rb +134 -0
  26. data/lib/photo_utils/sensitivity.rb +44 -0
  27. data/lib/photo_utils/time.rb +53 -0
  28. data/lib/photo_utils/tool.rb +17 -0
  29. data/lib/photo_utils/tools/blur.rb +43 -0
  30. data/lib/photo_utils/tools/brightness.rb +20 -0
  31. data/lib/photo_utils/tools/calc_aperture.rb +45 -0
  32. data/lib/photo_utils/tools/cameras.rb +24 -0
  33. data/lib/photo_utils/tools/chart_dof.rb +146 -0
  34. data/lib/photo_utils/tools/compare.rb +305 -0
  35. data/lib/photo_utils/tools/dof.rb +42 -0
  36. data/lib/photo_utils/tools/dof_table.rb +45 -0
  37. data/lib/photo_utils/tools/film_test.rb +57 -0
  38. data/lib/photo_utils/tools/focal_length.rb +25 -0
  39. data/lib/photo_utils/tools/reciprocity.rb +36 -0
  40. data/lib/photo_utils/tools/test.rb +91 -0
  41. data/lib/photo_utils/value.rb +37 -0
  42. data/lib/photo_utils/version.rb +5 -0
  43. data/photo-utils.gemspec +29 -0
  44. data/test/aperture_test.rb +40 -0
  45. data/test/apex_test.rb +28 -0
  46. data/test/brightness_test.rb +36 -0
  47. data/test/length_test.rb +40 -0
  48. data/test/scene_test.rb +25 -0
  49. data/test/sensitivity_test.rb +36 -0
  50. data/test/time_test.rb +42 -0
  51. metadata +185 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 70d478e0579f15d1fdba607ac85c84827ba8cea2
4
+ data.tar.gz: 53980404437217abd59062595727a0734aeb8fef
5
+ SHA512:
6
+ metadata.gz: 94bc1d34be20f01ff721d12a681a5487d6278f17a50d9edddb0d1a1472f08195d532ce6d9d61b4d00cfd7e8c8579ea117c4a7c3af2c0bb91b653aed0dcad248e
7
+ data.tar.gz: fc13ab1c3f0876db872371ee1bbf6082889333702faa349a6ed5f75e4c8474dee0cb9b4a3dd5d7b8e0d8135e4d5ef3382c51a4203085e0e91bd6bbccee5e0403
@@ -0,0 +1,3 @@
1
+ .DS_Store
2
+ Gemfile.lock
3
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in photo-utils.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ FIXME
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,34 @@
1
+
2
+ - Create FieldCalculator class:
3
+ - Set subject distance/height/width/depth
4
+ - Does DoF calculations
5
+
6
+ - Create generic camera models:
7
+ - 35mm w/50mm lens
8
+ - 6x6 w/80mm lens
9
+ - 4x5 w/127mm lens
10
+ - APS-C w/? lens
11
+
12
+ - Create Subject class
13
+ - Height/width.
14
+ - Near/far depth of field.
15
+
16
+ - Add print size to Scene
17
+ - Calculate best CoC according to print size
18
+
19
+ - Create Medium class?
20
+ - eg, film, plate, instant, CCD/CMOS
21
+ - With #sensitivity.
22
+
23
+ - Add common brightness values to Brightness class.
24
+ - eg, open shade, bright sun, etc.
25
+
26
+ - Add lighting formulas:
27
+ http://www.lightsearch.com/resources/lightguides/formulas.html
28
+ http://www.birket.com/technical-library/143/
29
+
30
+ - Add flash calculation
31
+
32
+ http://www.scantips.com/lights/flashbasics1c.html
33
+ http://www.portraitlighting.net/inversesquare_law.htm
34
+ http://en.wikipedia.org/wiki/Guide_number
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.join(File.realpath(File.dirname($0)), '..', 'lib'))
4
+
5
+ require 'photo_utils'
6
+ require 'photo_utils/tools/reciprocity'
7
+ require 'photo_utils/tools/focal_length'
8
+ require 'photo_utils/tools/test'
9
+ require 'photo_utils/tools/dof_table'
10
+ require 'photo_utils/tools/dof'
11
+ require 'photo_utils/tools/compare'
12
+ require 'photo_utils/tools/blur'
13
+ require 'photo_utils/tools/film_test'
14
+ require 'photo_utils/tools/brightness'
15
+ require 'photo_utils/tools/cameras'
16
+ require 'photo_utils/tools/calc_aperture'
17
+ require 'photo_utils/tools/chart_dof'
18
+
19
+ options = {}
20
+ appname = File.basename($0)
21
+
22
+ commands = {
23
+ 'reciprocity' => PhotoUtils::Tools::Reciprocity,
24
+ 'focal-length' => PhotoUtils::Tools::FocalLength,
25
+ 'test' => PhotoUtils::Tools::Test,
26
+ 'dof-table' => PhotoUtils::Tools::DOFTable,
27
+ 'dof' => PhotoUtils::Tools::DOF,
28
+ 'compare' => PhotoUtils::Tools::Compare,
29
+ 'blur' => PhotoUtils::Tools::Blur,
30
+ 'film-test' => PhotoUtils::Tools::FilmTest,
31
+ 'brightness' => PhotoUtils::Tools::Brightness,
32
+ 'cameras' => PhotoUtils::Tools::Cameras,
33
+ 'calc-aperture' => PhotoUtils::Tools::CalcAperture,
34
+ 'chart-dof' => PhotoUtils::Tools::ChartDOF,
35
+ }
36
+
37
+ cmd = ARGV.shift or raise "Usage"
38
+ cmd_class = commands[cmd] or raise "Usage"
39
+ cmd_class.new.run(ARGV)
@@ -0,0 +1,28 @@
1
+ require 'pp'
2
+ require 'hashstruct'
3
+ require 'builder'
4
+ require 'path'
5
+
6
+ require 'photo_utils/extensions/math'
7
+ require 'photo_utils/extensions/array'
8
+ require 'photo_utils/extensions/float'
9
+ require 'photo_utils/extensions/numeric'
10
+
11
+ require 'photo_utils/length'
12
+ require 'photo_utils/angle'
13
+ require 'photo_utils/value'
14
+
15
+ require 'photo_utils/aperture'
16
+ require 'photo_utils/brightness'
17
+ require 'photo_utils/compensation'
18
+ require 'photo_utils/illuminance'
19
+ require 'photo_utils/sensitivity'
20
+ require 'photo_utils/time'
21
+
22
+ require 'photo_utils/apex'
23
+ require 'photo_utils/lens'
24
+ require 'photo_utils/camera'
25
+ require 'photo_utils/frame'
26
+ require 'photo_utils/formats'
27
+ require 'photo_utils/scene'
28
+ require 'photo_utils/scene_view'
@@ -0,0 +1,17 @@
1
+ require 'delegate'
2
+
3
+ module PhotoUtils
4
+
5
+ class Angle < DelegateClass(Float)
6
+
7
+ def initialize(n)
8
+ super(n.to_f)
9
+ end
10
+
11
+ def to_s
12
+ "#{format}°"
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,62 @@
1
+ module PhotoUtils
2
+
3
+ class Aperture < Value
4
+
5
+ def self.new_from_fstop(f)
6
+ new(f)
7
+ end
8
+
9
+ def self.new_from_v(v)
10
+ new(Math.sqrt(2 ** v.to_f))
11
+ end
12
+
13
+ def to_v
14
+ Math.log2(self ** 2)
15
+ end
16
+
17
+ def format_fstop(stop_steps=3)
18
+ rounded_f = Aperture.new_from_v((to_v.to_f * stop_steps).to_i / stop_steps.to_f).format(10)
19
+ frac = rounded_f.to_f - rounded_f.to_i
20
+ if frac != 0
21
+ "f/#{rounded_f.to_f}"
22
+ else
23
+ "f/#{rounded_f.to_i}"
24
+ end
25
+ end
26
+
27
+ def format_us
28
+ # Av 8 is equivalent to f/16 and US 16
29
+ steps = to_v.to_i - 8
30
+ us = 16
31
+ if steps < 0
32
+ steps.abs.times { us /= 2 }
33
+ else
34
+ steps.times { us *= 2 }
35
+ end
36
+ "US #{us}"
37
+ end
38
+
39
+ def format_value
40
+ "Av:#{to_v.format(10)}"
41
+ end
42
+
43
+ def to_s(format=:fstop, stop_steps=3)
44
+ case format
45
+ when :us
46
+ format_us
47
+ when :fstop
48
+ format_fstop(stop_steps)
49
+ when :value
50
+ format_value
51
+ else
52
+ raise "Unknown format: #{format.inspect}"
53
+ end
54
+ end
55
+
56
+ def absolute(focal_length)
57
+ focal_length / self
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,210 @@
1
+ module PhotoUtils
2
+
3
+ class Exposure
4
+
5
+ =begin
6
+
7
+ http://doug.kerr.home.att.net/pumpkin/APEX.pdf
8
+ http://en.wikipedia.org/wiki/APEX_system
9
+ http://en.wikipedia.org/wiki/Exposure_value
10
+ http://en.wikipedia.org/wiki/Light_meter#Exposure_meter_calibration
11
+
12
+ basic APEX formula:
13
+ Ev = Tv + Av = Sv + Bv
14
+
15
+ logarithmic to linear equations:
16
+ 2^Av = N^2 (N is f-Number)
17
+ 2^Tv = 1/T (T in seconds)
18
+ 2^Sv = S/π (S is ASA film speed, now ISO)
19
+ 2^Bv = Bl (Bl in foot-lamberts) = B/π (B in candles per square foot)
20
+
21
+ base values:
22
+ Tv = 0 for a time (shutter speed) of one second.
23
+ Av = 0 for an aperture of f/1.
24
+ Sv = 0 for a film speed of ISO 3.125 arithmetic (and hence Sv = 5 for ISO 100).
25
+ Bv = 0 for a scene brightness of 1 foot-lambert.
26
+
27
+ calculate time from exposure and aperture
28
+ Tv = Ev - Av
29
+
30
+ calculate time from brightness, sensitivity, and aperture
31
+ Tv = (Sv + Bv) - Av
32
+
33
+ calculate brightness from Ev and sensitivity
34
+ Bv = Ev - Sv
35
+
36
+ calculate Ev from aperture, time, and film speed
37
+ Ev = (Tv + Av) - Sv
38
+
39
+ =end
40
+
41
+ attr_accessor :aperture
42
+ attr_accessor :time
43
+ attr_accessor :sensitivity
44
+ attr_accessor :light
45
+ attr_accessor :compensation
46
+
47
+ def initialize(params={})
48
+ params.each do |key, value|
49
+ send("#{key}=", value)
50
+ end
51
+ end
52
+
53
+ def aperture=(n)
54
+ @aperture = n ? Aperture.new(n) : nil
55
+ end
56
+
57
+ def time=(n)
58
+ @time = n ? Time.new(n) : nil
59
+ end
60
+
61
+ def sensitivity=(n)
62
+ @sensitivity = n ? Sensitivity.new(n) : nil
63
+ end
64
+
65
+ def light=(n)
66
+ @light = case n
67
+ when Brightness, Illuminance
68
+ n
69
+ when Numeric
70
+ Brightness.new(n)
71
+ when nil
72
+ nil
73
+ else
74
+ raise
75
+ end
76
+ end
77
+
78
+ def compensation=(n)
79
+ @compensation = n ? Compensation.new_from_v(n) : nil
80
+ end
81
+
82
+ def aperture
83
+ if @aperture
84
+ @aperture
85
+ elsif @sensitivity && @light && @time
86
+ Aperture.new_from_v(sv + lv - tv + cv)
87
+ else
88
+ raise "Need sensitivity/light/time to compute aperture"
89
+ end
90
+ end
91
+
92
+ def time
93
+ if @time
94
+ @time
95
+ elsif @sensitivity && @light && @aperture
96
+ Time.new_from_v(sv + lv - av + cv)
97
+ else
98
+ raise "Need sensitivity/light/aperture to compute time"
99
+ end
100
+ end
101
+
102
+ def sensitivity
103
+ if @sensitivity
104
+ @sensitivity
105
+ elsif @aperture && @time && @light
106
+ Sensitivity.new_from_v(av + tv - bv + cv)
107
+ else
108
+ raise "Need aperture/time/light to compute sensitivity"
109
+ end
110
+ end
111
+
112
+ def brightness
113
+ if @light
114
+ Brightness.new_from_v(lv)
115
+ elsif @aperture && @time && @sensitivity
116
+ Brightness.new_from_v(av + tv - sv + cv)
117
+ else
118
+ raise "Need aperture/time/sensitivity to compute brightness"
119
+ end
120
+ end
121
+
122
+ def illuminance
123
+ if @light
124
+ Illuminance.new_from_v(lv)
125
+ elsif @aperture && @time && @sensitivity
126
+ Illuminance.new_from_v(av + tv - sv + cv)
127
+ else
128
+ raise "Need aperture/time/sensitivity to compute illuminance"
129
+ end
130
+ end
131
+
132
+ def exposure
133
+ if @aperture && @time
134
+ av + tv
135
+ elsif @sensitivity && @light
136
+ sv + lv + cv
137
+ else
138
+ raise "Need aperture/time or sensitivity/light to compute exposure"
139
+ end
140
+ end
141
+
142
+ def av
143
+ aperture.to_v
144
+ end
145
+
146
+ def tv
147
+ time.to_v
148
+ end
149
+
150
+ def sv
151
+ sensitivity.to_v
152
+ end
153
+
154
+ def bv
155
+ brightness.to_v
156
+ end
157
+
158
+ def iv
159
+ illuminance.to_v
160
+ end
161
+
162
+ def lv
163
+ light.to_v
164
+ end
165
+
166
+ def cv
167
+ @compensation ? @compensation.to_f : 0
168
+ end
169
+
170
+ def ev
171
+ exposure
172
+ end
173
+
174
+ def ev100
175
+ ev - sv - Sensitivity.new(100).to_v
176
+ end
177
+
178
+ def stepped_exposures(steps=7, increment=0.3)
179
+ n = increment * (steps / 2)
180
+ (-n..n).step(increment).map do |adjustment|
181
+ new_exposure = dup
182
+ new_exposure.compensation = (@compensation ? @compensation : 0) + adjustment
183
+ new_exposure
184
+ end
185
+ end
186
+
187
+ def to_s
188
+ "%s = %s + %s = %s + %s" % [
189
+ "Ev:#{ev.format(10)}",
190
+ aperture.format_value,
191
+ time.format_value,
192
+ sensitivity.format_value,
193
+ light.format_value,
194
+ ]
195
+ end
196
+
197
+ def print(io=STDOUT)
198
+ io.puts "EXPOSURE:"
199
+ io.puts " light: #{light} (#{light.format_value})"
200
+ io.puts " sensitivity: #{sensitivity} (#{sensitivity.format_value})"
201
+ io.puts " aperture: #{aperture} (#{aperture.format_value})"
202
+ io.puts " time: #{time} (#{time.format_value})"
203
+ io.puts " compensation: #{@compensation ? compensation.format_value : '--'}"
204
+ io.puts " exposure: #{to_s}"
205
+ io.puts
206
+ end
207
+
208
+ end
209
+
210
+ end
@@ -0,0 +1,49 @@
1
+ module PhotoUtils
2
+
3
+ class Brightness < Value
4
+
5
+ # N = 2 ** Rational(-7, 4)
6
+ N = 0.3
7
+ K = 11.4
8
+ NK = N * K
9
+
10
+ # amount specified in cd/m2
11
+
12
+ def self.new_from_v(v)
13
+ new((2 ** v.to_f) * NK)
14
+ end
15
+
16
+ def self.new_from_cdm2(n)
17
+ new(n)
18
+ end
19
+
20
+ def to_v
21
+ Math.log2(self.to_f / NK)
22
+ end
23
+
24
+ def to_cdm2
25
+ to_f
26
+ end
27
+
28
+ def format_cdm2
29
+ to_cdm2.format(10) + ' cd/m2'
30
+ end
31
+
32
+ def format_value
33
+ "Bv:#{to_v.format}"
34
+ end
35
+
36
+ def to_s(format=:cdm2)
37
+ case format
38
+ when :cdm2
39
+ format_cdm2
40
+ when :value
41
+ format_value
42
+ else
43
+ raise "Unknown format: #{format.inspect}"
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ end