5
5
using System . Reflection ;
6
6
7
7
// Started with the code posted here: https://stackoverflow.com/a/18189027/206
8
+ // Cloned from https://github.com/anotherlab/FocusUF to add other camera properties
8
9
9
10
namespace FocusUF
10
11
{
@@ -17,21 +18,30 @@ public enum Operation
17
18
AutoExposure = 4 ,
18
19
SetFocus = 5 ,
19
20
SetExposure = 6 ,
20
- ListCameras = 7
21
+ ListCameras = 7 ,
22
+ Contrast = 8 ,
23
+ Saturation = 9 ,
24
+ Brightness = 10 ,
25
+ Gamma = 11 ,
26
+ NULL = - 1
21
27
}
22
28
23
29
class Program
24
30
{
25
31
// Global argument values
26
32
static Operation _whatToDo = Operation . Usage ;
27
- static string _cameraName = "Microsoft® LifeCam " ; // Assuming only one lifecam plugged in
33
+ static string _cameraName = "USB Camera " ; // Assuming only one lifecam plugged in
28
34
static int _focusSetting ;
29
35
static int _exposureSetting ;
36
+ static int _contrastSetting ;
37
+ static int _saturationSetting ;
38
+ static int _brightnessSetting ;
39
+ static int _gammaSetting ;
30
40
31
41
static void Main ( string [ ] args )
32
42
{
33
- Console . WriteLine ( "FocusUF " + Assembly . GetEntryAssembly ( ) . GetName ( ) . Version ) ;
34
- Console . WriteLine ( "Get the source at https://github.com/anotherlab /FocusUF" ) ;
43
+ Console . WriteLine ( "FocusUF-ng " + Assembly . GetEntryAssembly ( ) . GetName ( ) . Version ) ;
44
+ Console . WriteLine ( "Get the source at https://github.com/gpapp /FocusUF" ) ;
35
45
36
46
var argsLists = SplitArgs ( args . ToList ( ) ) ;
37
47
@@ -97,6 +107,22 @@ static void Main(string[] args)
97
107
case Operation . SetExposure :
98
108
SetCameraValue ( devs , _cameraName , CameraControlProperty . Exposure , _exposureSetting ) ;
99
109
break ;
110
+
111
+ case Operation . Saturation :
112
+ SetVideoProcValue ( devs , _cameraName , VideoProcAmpProperty . Saturation , _saturationSetting ) ;
113
+ break ;
114
+
115
+ case Operation . Gamma :
116
+ SetVideoProcValue ( devs , _cameraName , VideoProcAmpProperty . Gamma , _gammaSetting ) ;
117
+ break ;
118
+
119
+ case Operation . Brightness :
120
+ SetVideoProcValue ( devs , _cameraName , VideoProcAmpProperty . Brightness , _brightnessSetting ) ;
121
+ break ;
122
+
123
+ case Operation . Contrast :
124
+ SetVideoProcValue ( devs , _cameraName , VideoProcAmpProperty . Contrast , _contrastSetting ) ;
125
+ break ;
100
126
}
101
127
}
102
128
@@ -126,6 +152,30 @@ static IAMCameraControl GetCamera(DsDevice dev)
126
152
}
127
153
return _camera ;
128
154
}
155
+ /// <summary>
156
+ /// Gets a video processor inteface we can use from the generic device
157
+ /// </summary>
158
+ /// <param name="dev"></param>
159
+ /// <returns></returns>
160
+ static IAMVideoProcAmp GetVideoProcAmp ( DsDevice dev )
161
+ {
162
+ IAMVideoProcAmp _camera = dev as IAMVideoProcAmp ;
163
+ if ( dev != null )
164
+ {
165
+ // DirectShow uses a module system called filters to exposure the functionality
166
+ // We create a new object that implements the IFilterGraph2 interface so that we can
167
+ // new filters to exposure the functionality that we need.
168
+ if ( new FilterGraph ( ) is IFilterGraph2 graphBuilder )
169
+ {
170
+ // Create a video capture filter for the device
171
+ graphBuilder . AddSourceFilterForMoniker ( dev . Mon , null , dev . Name , out IBaseFilter capFilter ) ;
172
+
173
+ // Cast that filter to IAMCameraControl from the DirectShowLib
174
+ _camera = capFilter as IAMVideoProcAmp ;
175
+ }
176
+ }
177
+ return _camera ;
178
+ }
129
179
130
180
static void SetCameraFlag ( DsDevice [ ] devs , string cameraName , CameraControlProperty camProperty , CameraControlFlags flagVal )
131
181
{
@@ -179,6 +229,38 @@ static void SetCameraValue(DsDevice[] devs, string cameraName, CameraControlProp
179
229
}
180
230
}
181
231
232
+ static void SetVideoProcValue ( DsDevice [ ] devs , string cameraName , VideoProcAmpProperty property , int val )
233
+ {
234
+ IAMVideoProcAmp videoProcAmp = GetVideoProcAmp ( devs . Where ( d => d . Name . ToLower ( ) . Contains ( cameraName . ToLower ( ) ) ) . FirstOrDefault ( ) ) ;
235
+ videoProcAmp . GetRange ( property , out int min , out int max , out int steppingDelta , out int defaultValue , out var flags ) ;
236
+
237
+ Console . WriteLine ( $ "min: { min } , max: { max } , steppingDelta: { steppingDelta } defaultValue: { defaultValue } , flags: { flags } ") ;
238
+ val = Math . Min ( val , max ) ;
239
+ val = Math . Max ( val , min ) ;
240
+ if ( videoProcAmp != null )
241
+ {
242
+ // Get the current settings from the webcam
243
+ videoProcAmp . Get ( property , out int v , out VideoProcAmpFlags f ) ;
244
+
245
+ // If the camera value differs from the desired value, adjust it leaving flag the same.
246
+ if ( v != val )
247
+ {
248
+ videoProcAmp . Set ( property , val , f ) ;
249
+ Console . WriteLine ( $ "{ cameraName } { property } value set to { val } ") ;
250
+ }
251
+ else
252
+ {
253
+ Console . WriteLine ( $ "{ cameraName } { property } value already { val } ") ;
254
+ }
255
+ videoProcAmp . Get ( property , out int v2 , out VideoProcAmpFlags f2 ) ;
256
+ Console . WriteLine ( $ "Setting { property } value { ( val == v2 ? "successful" : "failed" ) } { cameraName } { property } value is at { v2 } ") ;
257
+ }
258
+ else
259
+ {
260
+ Console . WriteLine ( $ "No physical camera matching \" { cameraName } \" found") ;
261
+ }
262
+ }
263
+
182
264
/// <summary>
183
265
/// Split the argument list on "--and" into multiple lists
184
266
/// </summary>
@@ -246,8 +328,39 @@ static Operation ProcessArgs(List<string> args)
246
328
return Operation . SetExposure ;
247
329
}
248
330
331
+ Int32 argVal ;
332
+ if ( ( argVal = processArgument ( args , "brightness" , "b" ) ) != int . MinValue ) {
333
+ _brightnessSetting = argVal ;
334
+ return Operation . Brightness ;
335
+ }
336
+ if ( ( argVal = processArgument ( args , "contrast" , "c" ) ) != int . MinValue )
337
+ {
338
+ _contrastSetting = argVal ;
339
+ return Operation . Contrast ;
340
+ }
341
+ if ( ( argVal = processArgument ( args , "saturation" , "s" ) ) != int . MinValue )
342
+ {
343
+ _saturationSetting = argVal ;
344
+ return Operation . Saturation ;
345
+ }
346
+ if ( ( argVal = processArgument ( args , "gamma" , "g" ) ) != int . MinValue )
347
+ {
348
+ _gammaSetting = argVal ;
349
+ return Operation . Gamma ;
350
+ }
351
+
249
352
return Operation . Usage ;
250
353
}
354
+ private static int processArgument ( List < string > args , String longArg , String shortArg )
355
+ {
356
+ var argIx = args . IndexOf ( "--set-" + longArg ) ;
357
+ argIx = argIx != - 1 ? argIx : args . IndexOf ( "-" + shortArg ) ;
358
+ if ( argIx != - 1 && args . Count >= argIx + 2 && int . TryParse ( args [ argIx + 1 ] , out int expVal ) )
359
+ {
360
+ return expVal ;
361
+ }
362
+ return int . MinValue ;
363
+ }
251
364
252
365
static void Usage ( )
253
366
{
@@ -257,6 +370,10 @@ static void Usage()
257
370
[--set-focus <value> | -f <value>]
258
371
[--exposure-mode-manual | -em] [--exposure-mode-auto | -ea]
259
372
[--set-exposure <value> | -e <value>]
373
+ [--set-brightness <value> | -b <value>]
374
+ [--set-contrast <value> | -c <value>]
375
+ [--set-saturation <value> | -s <value>]
376
+ [--set-gamma <value> | -g <value>]
260
377
[--camera-name <name> | -n <name>]
261
378
[--and {more operations...}]" ) ;
262
379
}
0 commit comments