Skip to content

Commit f94036c

Browse files
committed
Added support for setting brightness, contrast, gamma, saturation
1 parent b52ba8f commit f94036c

File tree

6 files changed

+159
-11
lines changed

6 files changed

+159
-11
lines changed

FocusUF/App.config

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<?xml version="1.0" encoding="utf-8" ?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<configuration>
33
<startup>
4-
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
55
</startup>
6-
</configuration>
6+
</configuration>

FocusUF/FocusUF.csproj

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,25 @@
88
<OutputType>Exe</OutputType>
99
<RootNamespace>FocusUF</RootNamespace>
1010
<AssemblyName>FocusUF</AssemblyName>
11-
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
11+
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
1212
<FileAlignment>512</FileAlignment>
1313
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
14+
<TargetFrameworkProfile />
15+
<PublishUrl>publish\</PublishUrl>
16+
<Install>true</Install>
17+
<InstallFrom>Disk</InstallFrom>
18+
<UpdateEnabled>false</UpdateEnabled>
19+
<UpdateMode>Foreground</UpdateMode>
20+
<UpdateInterval>7</UpdateInterval>
21+
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
22+
<UpdatePeriodically>false</UpdatePeriodically>
23+
<UpdateRequired>false</UpdateRequired>
24+
<MapFileExtensions>true</MapFileExtensions>
25+
<ApplicationRevision>0</ApplicationRevision>
26+
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
27+
<IsWebBootstrapper>false</IsWebBootstrapper>
28+
<UseApplicationTrust>false</UseApplicationTrust>
29+
<BootstrapperEnabled>true</BootstrapperEnabled>
1430
</PropertyGroup>
1531
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
1632
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -52,5 +68,17 @@
5268
<None Include="App.config" />
5369
<None Include="packages.config" />
5470
</ItemGroup>
71+
<ItemGroup>
72+
<BootstrapperPackage Include=".NETFramework,Version=v4.8">
73+
<Visible>False</Visible>
74+
<ProductName>Microsoft .NET Framework 4.8 %28x86 and x64%29</ProductName>
75+
<Install>true</Install>
76+
</BootstrapperPackage>
77+
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
78+
<Visible>False</Visible>
79+
<ProductName>.NET Framework 3.5 SP1</ProductName>
80+
<Install>false</Install>
81+
</BootstrapperPackage>
82+
</ItemGroup>
5583
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
5684
</Project>

FocusUF/Program.cs

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66

77
// 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
89

910
namespace FocusUF
1011
{
@@ -17,21 +18,30 @@ public enum Operation
1718
AutoExposure = 4,
1819
SetFocus = 5,
1920
SetExposure = 6,
20-
ListCameras = 7
21+
ListCameras = 7,
22+
Contrast = 8,
23+
Saturation = 9,
24+
Brightness = 10,
25+
Gamma = 11,
26+
NULL =- 1
2127
}
2228

2329
class Program
2430
{
2531
// Global argument values
2632
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
2834
static int _focusSetting;
2935
static int _exposureSetting;
36+
static int _contrastSetting;
37+
static int _saturationSetting;
38+
static int _brightnessSetting;
39+
static int _gammaSetting;
3040

3141
static void Main(string[] args)
3242
{
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");
3545

3646
var argsLists = SplitArgs(args.ToList());
3747

@@ -97,6 +107,22 @@ static void Main(string[] args)
97107
case Operation.SetExposure:
98108
SetCameraValue(devs, _cameraName, CameraControlProperty.Exposure, _exposureSetting);
99109
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;
100126
}
101127
}
102128

@@ -126,6 +152,30 @@ static IAMCameraControl GetCamera(DsDevice dev)
126152
}
127153
return _camera;
128154
}
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+
}
129179

130180
static void SetCameraFlag (DsDevice[] devs, string cameraName, CameraControlProperty camProperty, CameraControlFlags flagVal)
131181
{
@@ -179,6 +229,38 @@ static void SetCameraValue(DsDevice[] devs, string cameraName, CameraControlProp
179229
}
180230
}
181231

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+
182264
/// <summary>
183265
/// Split the argument list on "--and" into multiple lists
184266
/// </summary>
@@ -246,8 +328,39 @@ static Operation ProcessArgs(List<string> args)
246328
return Operation.SetExposure;
247329
}
248330

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+
249352
return Operation.Usage;
250353
}
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+
}
251364

252365
static void Usage()
253366
{
@@ -257,6 +370,10 @@ static void Usage()
257370
[--set-focus <value> | -f <value>]
258371
[--exposure-mode-manual | -em] [--exposure-mode-auto | -ea]
259372
[--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>]
260377
[--camera-name <name> | -n <name>]
261378
[--and {more operations...}]");
262379
}

FocusUF/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.2.0.0")]
36-
[assembly: AssemblyFileVersion("1.2.0.0")]
35+
[assembly: AssemblyVersion("1.3.0.0")]
36+
[assembly: AssemblyFileVersion("1.3.0.0")]

FocusUF/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="DirectShowLib" version="1.0.0" targetFramework="net461" />
3+
<package id="DirectShowLib" version="1.0.0" targetFramework="net48" />
44
</packages>

sh.exe.stackdump

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Stack trace:
2+
Frame Function Args
3+
0080B9A8 6108D625 (00000011, 00000004, 00000004, E107DD01)

0 commit comments

Comments
 (0)