├── src
├── KinectCam
│ ├── KinectCam.snk
│ ├── Resources
│ │ └── dx5_logo.bmp
│ ├── app.config
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── Threading.cs
│ ├── install.bat
│ ├── uninstall.bat
│ ├── KinectCamSettigns.cs
│ ├── IconExtractor.cs
│ ├── AboutForm.cs
│ ├── AboutForm.resx
│ ├── AboutForm.Designer.cs
│ ├── KinectCam.csproj
│ ├── KinectHelper.cs
│ └── VirtualCam.cs
├── BaseClasses
│ ├── BaseClassesNET.snk
│ ├── app.config
│ └── BaseClasses.csproj
└── KinectCam.sln
├── .gitattributes
├── .gitignore
├── LICENSE
└── README.md
/src/KinectCam/KinectCam.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavidObando/KinectCamV2/HEAD/src/KinectCam/KinectCam.snk
--------------------------------------------------------------------------------
/src/BaseClasses/BaseClassesNET.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavidObando/KinectCamV2/HEAD/src/BaseClasses/BaseClassesNET.snk
--------------------------------------------------------------------------------
/src/KinectCam/Resources/dx5_logo.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DavidObando/KinectCamV2/HEAD/src/KinectCam/Resources/dx5_logo.bmp
--------------------------------------------------------------------------------
/src/BaseClasses/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/KinectCam/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/KinectCam/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/KinectCam/Threading.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace System.Windows
7 | {
8 | class Threading
9 | {
10 | public static object DispatcherOperation { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/KinectCam/install.bat:
--------------------------------------------------------------------------------
1 | @c:
2 | @cd c:\KinectCamV21\
3 |
4 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install BaseClassesNET.dll
5 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install KinectCam.dll
6 |
7 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /nologo BaseClassesNET.dll
8 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe KinectCam.dll /nologo /codebase /tlb: KinectCam.tlb
9 |
--------------------------------------------------------------------------------
/src/KinectCam/uninstall.bat:
--------------------------------------------------------------------------------
1 | @c:
2 | @cd c:\KinectCamV21\
3 |
4 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /unregister /nologo BaseClassesNET.dll
5 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe /unregister /nologo KinectCam.dll
6 |
7 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe uninstall BaseClassesNET.dll
8 | @c:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe uninstall KinectCam.dll
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | [Oo]bj/
2 | [Bb]in/
3 | TestResults/
4 | .nuget/
5 | _ReSharper.*/
6 | packages/
7 | artifacts/
8 | PublishProfiles/
9 | *.user
10 | *.suo
11 | *.cache
12 | *.docstates
13 | _ReSharper.*
14 | nuget.exe
15 | *net45.csproj
16 | *net451.csproj
17 | *k10.csproj
18 | *.psess
19 | *.vsp
20 | *.pidb
21 | *.userprefs
22 | *DS_Store
23 | *.ncrunchsolution
24 | *.*sdf
25 | *.ipch
26 | *.sln.ide
27 | *.lock.json
28 | *.db
29 | .vs/
30 | config.test.json
31 | *.log
32 |
--------------------------------------------------------------------------------
/src/KinectCam/KinectCamSettigns.cs:
--------------------------------------------------------------------------------
1 | namespace KinectCam
2 | {
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | internal sealed class KinectCamSettigns
7 | {
8 |
9 | private static KinectCamSettigns defaultInstance = new KinectCamSettigns();
10 |
11 | public static KinectCamSettigns Default
12 | {
13 | get
14 | {
15 | return defaultInstance;
16 | }
17 | }
18 |
19 | public bool Mirrored
20 | {
21 | get;
22 | set;
23 | }
24 |
25 | public bool Zoom
26 | {
27 | get;
28 | set;
29 | }
30 | public bool TrackHead
31 | {
32 | get;
33 | set;
34 | }
35 | public bool Desktop
36 | {
37 | get;
38 | set;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/KinectCam/IconExtractor.cs:
--------------------------------------------------------------------------------
1 | namespace KinectCam
2 | {
3 | using System;
4 | using System.Drawing;
5 | using System.IO;
6 | using System.Runtime.InteropServices;
7 |
8 | public class IconExtractor
9 | {
10 |
11 | public static Icon Extract(int number, bool largeIcon)
12 | {
13 | IntPtr large;
14 | IntPtr small;
15 | var file = Path.Combine(Environment.SystemDirectory, "shell32.dll");
16 | ExtractIconEx(file, number, out large, out small, 1);
17 | try
18 | {
19 | return Icon.FromHandle(largeIcon ? large : small);
20 | }
21 | catch
22 | {
23 | return null;
24 | }
25 |
26 | }
27 | [DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
28 | private static extern int ExtractIconEx(string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons);
29 |
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 David Obando
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/KinectCam/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18408
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace KinectCam.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/KinectCam/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using System;
5 | using System.Security.Permissions;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("KinectCamV2")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("")]
15 | [assembly: AssemblyCopyright("Copyright © Piotr Sowa 2014")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(true)]
23 |
24 | // The following GUID is for the ID of the typelib if this project is exposed to COM
25 | [assembly: Guid("65C5EB73-5B3E-47E4-B9B5-BDAFFBE3CE69")]
26 |
27 | // Version information for an assembly consists of the following four values:
28 | //
29 | // Major Version
30 | // Minor Version
31 | // Build Number
32 | // Revision
33 | //
34 |
35 | [assembly: SecurityPermission(SecurityAction.RequestMinimum, UnmanagedCode = true)]
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # KinectCamV2
3 | Original code is from Piotr Sowa:
4 | * http://codingbytodesign.net/2014/07/20/kinectcamv2-for-kinect-v2/
5 | * http://codingbytodesign.net/2015/02/08/coding-by-to-design-of-kinectcamv2/
6 |
7 | The code is functional with Kinect for Xbox One and the v2 SDK, but it hasn't been sanitized as of this commit. However, the project has been cleaned to not mess with your file system.
8 |
9 | Also, make sure you enable Windows Hello with your Kinect. It works perfectly! https://channel9.msdn.com/coding4fun/kinect/Windows-Hello-with-the-Kinect-v2
10 |
11 | ## Skype for Business
12 | Also from http://codingbytodesign.net/2014/07/20/kinectcamv2-for-kinect-v2/:
13 | Many people want to use this solution for Skype for Business 2016 or older. The solution is very simple, because Skype for Business 2016 and older uses .NET Framework 2.0 runtime and KinectCamV2 driver is written in .NET Framework 4.0, so to force Skype for Business 2016 or older to use .NET Framework 4.0 all you have to do is very simple thing. You have to create lync.exe.config file with following content.
14 | ```xml
15 |
16 |
17 |
18 |
19 |
20 |
21 | ```
22 | And copy it to the place where you have lync.exe installed, for example inside folder: “C:\Program Files (x86)\Microsoft Office\Root\Office16”. This solution can be used for other solutions that uses .NET Framework and you need force to use higer version of .NET Framework.
23 |
--------------------------------------------------------------------------------
/src/KinectCam/AboutForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Text;
7 | using System.Windows.Forms;
8 | using System.Runtime.InteropServices;
9 | using DirectShow.BaseClasses;
10 | using Microsoft.Kinect;
11 |
12 | namespace KinectCam
13 | {
14 | [ComVisible(true)]
15 | [Guid("A9017694-6378-4472-B5A2-55A41E476238")]
16 | public partial class AboutForm : BasePropertyPage
17 | {
18 | public AboutForm()
19 | {
20 | InitializeComponent();
21 | }
22 |
23 | private void AboutForm_Load(object sender, EventArgs e)
24 | {
25 | cbMirrored.Checked = KinectCamSettigns.Default.Mirrored;
26 | cbDesktop.Checked = KinectCamSettigns.Default.Desktop;
27 | cbZoom.Checked = KinectCamSettigns.Default.Zoom;
28 | cbTrackHead.Checked = KinectCamSettigns.Default.TrackHead;
29 | }
30 |
31 | private void cbMirrored_CheckedChanged(object sender, EventArgs e)
32 | {
33 | KinectCamSettigns.Default.Mirrored = cbMirrored.Checked;
34 | }
35 |
36 | private void cbDesktop_CheckedChanged(object sender, EventArgs e)
37 | {
38 | KinectCamSettigns.Default.Desktop = cbDesktop.Checked;
39 | }
40 |
41 | private void cbZoom_CheckedChanged(object sender, EventArgs e)
42 | {
43 | KinectCamSettigns.Default.Zoom = cbZoom.Checked;
44 | }
45 |
46 | private void cbTrackHead_CheckedChanged(object sender, EventArgs e)
47 | {
48 | KinectCamSettigns.Default.TrackHead = cbTrackHead.Checked;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/KinectCam/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18408
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace KinectCam.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("KinectCam.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Bitmap.
65 | ///
66 | internal static System.Drawing.Bitmap dx5_logo {
67 | get {
68 | object obj = ResourceManager.GetObject("dx5_logo", resourceCulture);
69 | return ((System.Drawing.Bitmap)(obj));
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/KinectCam.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KinectCam", ".\KinectCam\KinectCam.csproj", "{02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BaseClasses", ".\BaseClasses\BaseClasses.csproj", "{2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|Mixed Platforms = Debug|Mixed Platforms
12 | Debug|Win32 = Debug|Win32
13 | Debug|x64 = Debug|x64
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|Mixed Platforms = Release|Mixed Platforms
17 | Release|Win32 = Release|Win32
18 | Release|x64 = Release|x64
19 | Release|x86 = Release|x86
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
25 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
26 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|Win32.ActiveCfg = Debug|Any CPU
27 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|x64.ActiveCfg = Debug|x64
28 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|x64.Build.0 = Debug|x64
29 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Debug|x86.ActiveCfg = Debug|Any CPU
30 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
33 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|Mixed Platforms.Build.0 = Release|Any CPU
34 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|Win32.ActiveCfg = Release|Any CPU
35 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|x64.ActiveCfg = Release|x64
36 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|x64.Build.0 = Release|x64
37 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}.Release|x86.ActiveCfg = Release|Any CPU
38 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
41 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
42 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|Win32.ActiveCfg = Debug|Any CPU
43 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|x64.ActiveCfg = Debug|x64
44 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|x64.Build.0 = Debug|x64
45 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Debug|x86.ActiveCfg = Debug|Any CPU
46 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
47 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|Any CPU.Build.0 = Release|Any CPU
48 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
49 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|Mixed Platforms.Build.0 = Release|Any CPU
50 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|Win32.ActiveCfg = Release|Any CPU
51 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|x64.ActiveCfg = Release|x64
52 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|x64.Build.0 = Release|x64
53 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}.Release|x86.ActiveCfg = Release|Any CPU
54 | EndGlobalSection
55 | GlobalSection(SolutionProperties) = preSolution
56 | HideSolutionNode = FALSE
57 | EndGlobalSection
58 | EndGlobal
59 |
--------------------------------------------------------------------------------
/src/KinectCam/AboutForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/KinectCam/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\dx5_logo.bmp;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
--------------------------------------------------------------------------------
/src/BaseClasses/BaseClasses.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}
9 | Library
10 | Properties
11 | DirectShow.BaseClasses
12 | BaseClassesNET
13 | v4.5
14 | 512
15 |
16 |
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 0
28 | 1.0.0.%2a
29 | false
30 | false
31 | true
32 | true
33 | BaseClassesNET.snk
34 |
35 |
36 |
37 |
38 | 3.5
39 |
40 |
41 |
42 | true
43 | full
44 | false
45 | bin\AnyCPU\Debug
46 | DEBUG;TRACE
47 | prompt
48 | 4
49 | false
50 | Off
51 | false
52 | x86
53 | false
54 | false
55 |
56 |
57 | pdbonly
58 | true
59 | bin\AnyCPU\Release\
60 | TRACE
61 | prompt
62 | 4
63 | false
64 | false
65 | x86
66 | false
67 |
68 |
69 | true
70 | bin\x64\Debug\
71 | DEBUG;TRACE
72 | full
73 | x64
74 | false
75 | Off
76 | prompt
77 | MinimumRecommendedRules.ruleset
78 | false
79 |
80 |
81 | bin\x64\Release\
82 | TRACE
83 | true
84 | pdbonly
85 | x64
86 | false
87 | prompt
88 | MinimumRecommendedRules.ruleset
89 | false
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | False
101 | .NET Framework Client Profile
102 | false
103 |
104 |
105 | False
106 | .NET Framework 2.0 %28x86%29
107 | false
108 |
109 |
110 | False
111 | .NET Framework 3.0 %28x86%29
112 | false
113 |
114 |
115 | False
116 | .NET Framework 3.5
117 | false
118 |
119 |
120 | False
121 | .NET Framework 3.5 SP1
122 | true
123 |
124 |
125 | False
126 | Windows Installer 3.1
127 | true
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
150 |
--------------------------------------------------------------------------------
/src/KinectCam/AboutForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace KinectCam
2 | {
3 | partial class AboutForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.titleLabel = new System.Windows.Forms.Label();
32 | this.gbAuthors = new System.Windows.Forms.GroupBox();
33 | this.tbAuthors = new System.Windows.Forms.TextBox();
34 | this.cbMirrored = new System.Windows.Forms.CheckBox();
35 | this.cbDesktop = new System.Windows.Forms.CheckBox();
36 | this.gbOptions = new System.Windows.Forms.GroupBox();
37 | this.cbZoom = new System.Windows.Forms.CheckBox();
38 | this.cbTrackHead = new System.Windows.Forms.CheckBox();
39 | this.gbAuthors.SuspendLayout();
40 | this.gbOptions.SuspendLayout();
41 | this.SuspendLayout();
42 | //
43 | // titleLabel
44 | //
45 | this.titleLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
46 | | System.Windows.Forms.AnchorStyles.Right)));
47 | this.titleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
48 | this.titleLabel.Location = new System.Drawing.Point(12, 6);
49 | this.titleLabel.Name = "titleLabel";
50 | this.titleLabel.Size = new System.Drawing.Size(356, 38);
51 | this.titleLabel.TabIndex = 0;
52 | this.titleLabel.Text = "KinectCam ver. 2.2";
53 | this.titleLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
54 | //
55 | // gbAuthors
56 | //
57 | this.gbAuthors.Controls.Add(this.tbAuthors);
58 | this.gbAuthors.Location = new System.Drawing.Point(12, 138);
59 | this.gbAuthors.Name = "gbAuthors";
60 | this.gbAuthors.Size = new System.Drawing.Size(356, 70);
61 | this.gbAuthors.TabIndex = 7;
62 | this.gbAuthors.TabStop = false;
63 | this.gbAuthors.Text = "Authors";
64 | //
65 | // tbAuthors
66 | //
67 | this.tbAuthors.BorderStyle = System.Windows.Forms.BorderStyle.None;
68 | this.tbAuthors.Location = new System.Drawing.Point(6, 19);
69 | this.tbAuthors.Margin = new System.Windows.Forms.Padding(0);
70 | this.tbAuthors.Multiline = true;
71 | this.tbAuthors.Name = "tbAuthors";
72 | this.tbAuthors.ReadOnly = true;
73 | this.tbAuthors.Size = new System.Drawing.Size(344, 36);
74 | this.tbAuthors.TabIndex = 0;
75 | this.tbAuthors.Text = "VirtualCam and BaseClass created by Maxim Kartavenkov aka Sonic\r\nKinect Driver as" +
76 | " WebCam created by Piotr Sowa";
77 | //
78 | // cbMirrored
79 | //
80 | this.cbMirrored.AutoSize = true;
81 | this.cbMirrored.Location = new System.Drawing.Point(6, 19);
82 | this.cbMirrored.Name = "cbMirrored";
83 | this.cbMirrored.Size = new System.Drawing.Size(64, 17);
84 | this.cbMirrored.TabIndex = 5;
85 | this.cbMirrored.Text = "Mirrored";
86 | this.cbMirrored.UseVisualStyleBackColor = true;
87 | this.cbMirrored.CheckedChanged += new System.EventHandler(this.cbMirrored_CheckedChanged);
88 | //
89 | // cbDesktop
90 | //
91 | this.cbDesktop.AutoSize = true;
92 | this.cbDesktop.Location = new System.Drawing.Point(6, 42);
93 | this.cbDesktop.Name = "cbDesktop";
94 | this.cbDesktop.Size = new System.Drawing.Size(66, 17);
95 | this.cbDesktop.TabIndex = 6;
96 | this.cbDesktop.Text = "Desktop";
97 | this.cbDesktop.UseVisualStyleBackColor = true;
98 | this.cbDesktop.CheckedChanged += new System.EventHandler(this.cbDesktop_CheckedChanged);
99 | //
100 | // gbOptions
101 | //
102 | this.gbOptions.Controls.Add(this.cbDesktop);
103 | this.gbOptions.Controls.Add(this.cbTrackHead);
104 | this.gbOptions.Controls.Add(this.cbZoom);
105 | this.gbOptions.Controls.Add(this.cbMirrored);
106 | this.gbOptions.Location = new System.Drawing.Point(12, 47);
107 | this.gbOptions.Name = "gbOptions";
108 | this.gbOptions.Size = new System.Drawing.Size(356, 85);
109 | this.gbOptions.TabIndex = 6;
110 | this.gbOptions.TabStop = false;
111 | this.gbOptions.Text = "Options (only for current session)";
112 | //
113 | // cbZoom
114 | //
115 | this.cbZoom.AutoSize = true;
116 | this.cbZoom.Location = new System.Drawing.Point(76, 19);
117 | this.cbZoom.Name = "cbZoom";
118 | this.cbZoom.Size = new System.Drawing.Size(53, 17);
119 | this.cbZoom.TabIndex = 5;
120 | this.cbZoom.Text = "Zoom";
121 | this.cbZoom.UseVisualStyleBackColor = true;
122 | this.cbZoom.CheckedChanged += new System.EventHandler(this.cbZoom_CheckedChanged);
123 | //
124 | // cbTrackHead
125 | //
126 | this.cbTrackHead.AutoSize = true;
127 | this.cbTrackHead.Location = new System.Drawing.Point(76, 42);
128 | this.cbTrackHead.Name = "cbTrackHead";
129 | this.cbTrackHead.Size = new System.Drawing.Size(80, 17);
130 | this.cbTrackHead.TabIndex = 5;
131 | this.cbTrackHead.Text = "TrackHead";
132 | this.cbTrackHead.UseVisualStyleBackColor = true;
133 | this.cbTrackHead.CheckedChanged += new System.EventHandler(this.cbTrackHead_CheckedChanged);
134 | //
135 | // AboutForm
136 | //
137 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
138 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
139 | this.ClientSize = new System.Drawing.Size(380, 220);
140 | this.Controls.Add(this.gbAuthors);
141 | this.Controls.Add(this.gbOptions);
142 | this.Controls.Add(this.titleLabel);
143 | this.Name = "AboutForm";
144 | this.Text = "About";
145 | this.Title = "About";
146 | this.Load += new System.EventHandler(this.AboutForm_Load);
147 | this.gbAuthors.ResumeLayout(false);
148 | this.gbAuthors.PerformLayout();
149 | this.gbOptions.ResumeLayout(false);
150 | this.gbOptions.PerformLayout();
151 | this.ResumeLayout(false);
152 |
153 | }
154 |
155 | #endregion
156 |
157 | private System.Windows.Forms.Label titleLabel;
158 | private System.Windows.Forms.GroupBox gbAuthors;
159 | private System.Windows.Forms.TextBox tbAuthors;
160 | private System.Windows.Forms.CheckBox cbMirrored;
161 | private System.Windows.Forms.CheckBox cbDesktop;
162 | private System.Windows.Forms.GroupBox gbOptions;
163 | private System.Windows.Forms.CheckBox cbZoom;
164 | private System.Windows.Forms.CheckBox cbTrackHead;
165 | }
166 | }
--------------------------------------------------------------------------------
/src/KinectCam/KinectCam.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 9.0.30729
7 | 2.0
8 | {02D8455F-DDC1-4BC0-B85C-246CF8FD2A36}
9 | Library
10 | Properties
11 | KinectCam
12 | KinectCam
13 | v4.5
14 | 512
15 |
16 |
17 | false
18 | true
19 | false
20 | KinectCam.snk
21 |
22 |
23 |
24 |
25 | 3.5
26 | publish\
27 | true
28 | Disk
29 | false
30 | Foreground
31 | 7
32 | Days
33 | false
34 | false
35 | true
36 | 0
37 | 1.0.0.%2a
38 | false
39 | true
40 |
41 |
42 |
43 | true
44 | full
45 | false
46 | bin\AnyCPU\Debug\
47 | DEBUG;TRACE
48 | prompt
49 | 4
50 | false
51 | Off
52 | false
53 | x86
54 | true
55 | false
56 |
57 |
58 | pdbonly
59 | true
60 | bin\AnyCPU\Release\
61 | TRACE
62 | prompt
63 | 4
64 | false
65 | false
66 | x86
67 | Off
68 | true
69 | false
70 |
71 |
72 | true
73 | bin\x64\Debug\
74 | DEBUG;TRACE
75 | full
76 | x64
77 | false
78 | Off
79 | prompt
80 | MinimumRecommendedRules.ruleset
81 | false
82 |
83 |
84 | bin\x64\Release\
85 | TRACE
86 | true
87 | pdbonly
88 | x64
89 | false
90 | Off
91 | prompt
92 | MinimumRecommendedRules.ruleset
93 | false
94 |
95 |
96 |
97 | False
98 | ..\..\..\..\Program Files\Microsoft SDKs\Kinect\v2.0-PublicPreview1407\Assemblies\Microsoft.Kinect.dll
99 | False
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | False
110 | .NET Framework 3.5 SP1 Client Profile
111 | false
112 |
113 |
114 | False
115 | .NET Framework 2.0 %28x86%29
116 | false
117 |
118 |
119 | False
120 | .NET Framework 3.0 %28x86%29
121 | false
122 |
123 |
124 | False
125 | .NET Framework 3.5
126 | false
127 |
128 |
129 | False
130 | .NET Framework 3.5 SP1
131 | true
132 |
133 |
134 | False
135 | Windows Installer 3.1
136 | true
137 |
138 |
139 |
140 |
141 |
142 | PreserveNewest
143 |
144 |
145 | SettingsSingleFileGenerator
146 | Settings.Designer.cs
147 | Designer
148 |
149 |
150 | PreserveNewest
151 |
152 |
153 |
154 |
155 | Form
156 |
157 |
158 | AboutForm.cs
159 |
160 |
161 |
162 |
163 |
164 | True
165 | True
166 | Settings.settings
167 |
168 |
169 |
170 |
171 |
172 | True
173 | True
174 | Resources.resx
175 |
176 |
177 |
178 |
179 | AboutForm.cs
180 |
181 |
182 | ResXFileCodeGenerator
183 | Resources.Designer.cs
184 |
185 |
186 |
187 |
188 | {2A8E8AF5-74E7-49DB-A42E-9360FA7A6CC4}
189 | BaseClasses
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
204 |
--------------------------------------------------------------------------------
/src/KinectCam/KinectHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using Microsoft.Kinect;
4 | using System.Threading;
5 | using System.Windows.Forms;
6 | using System.Drawing;
7 | using System.IO;
8 |
9 | namespace KinectCam
10 | {
11 | public static class KinectHelper
12 | {
13 | class KinectCamApplicationContext : ApplicationContext
14 | {
15 | private NotifyIcon TrayIcon;
16 | private ContextMenuStrip TrayIconContextMenu;
17 | private ToolStripMenuItem MirroredMenuItem;
18 | private ToolStripMenuItem DesktopMenuItem;
19 | private ToolStripMenuItem ZoomMenuItem;
20 | private ToolStripMenuItem TrackHeadMenuItem;
21 | public KinectCamApplicationContext()
22 | {
23 | Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
24 | InitializeComponent();
25 | TrayIcon.Visible = true;
26 | //TrayIcon.ShowBalloonTip(30000);
27 | }
28 |
29 | private void InitializeComponent()
30 | {
31 | TrayIcon = new NotifyIcon();
32 |
33 | TrayIcon.BalloonTipIcon = ToolTipIcon.Info;
34 | TrayIcon.BalloonTipText =
35 | "For options use this tray icon.";
36 | TrayIcon.BalloonTipTitle = "KinectCamV2";
37 | TrayIcon.Text = "KinectCam";
38 |
39 | TrayIcon.Icon = IconExtractor.Extract(117, false);
40 |
41 | TrayIcon.DoubleClick += TrayIcon_DoubleClick;
42 |
43 | TrayIconContextMenu = new ContextMenuStrip();
44 | MirroredMenuItem = new ToolStripMenuItem();
45 | DesktopMenuItem = new ToolStripMenuItem();
46 | ZoomMenuItem = new ToolStripMenuItem();
47 | TrackHeadMenuItem = new ToolStripMenuItem();
48 | TrayIconContextMenu.SuspendLayout();
49 |
50 | //
51 | // TrayIconContextMenu
52 | //
53 | this.TrayIconContextMenu.Items.AddRange(new ToolStripItem[] {
54 | this.MirroredMenuItem,
55 | this.DesktopMenuItem,
56 | this.ZoomMenuItem,
57 | this.TrackHeadMenuItem
58 | });
59 | this.TrayIconContextMenu.Name = "TrayIconContextMenu";
60 | this.TrayIconContextMenu.Size = new Size(153, 70);
61 | //
62 | // MirroredMenuItem
63 | //
64 | this.MirroredMenuItem.Name = "Mirrored";
65 | this.MirroredMenuItem.Size = new Size(152, 22);
66 | this.MirroredMenuItem.Text = "Mirrored";
67 | this.MirroredMenuItem.Click += new EventHandler(this.MirroredMenuItem_Click);
68 |
69 | //
70 | // DesktopMenuItem
71 | //
72 | this.DesktopMenuItem.Name = "Desktop";
73 | this.DesktopMenuItem.Size = new Size(152, 22);
74 | this.DesktopMenuItem.Text = "Desktop";
75 | this.DesktopMenuItem.Click += new EventHandler(this.DesktopMenuItem_Click);
76 |
77 | //
78 | // ZoomMenuItem
79 | //
80 | this.ZoomMenuItem.Name = "Zoom";
81 | this.ZoomMenuItem.Size = new Size(152, 22);
82 | this.ZoomMenuItem.Text = "Zoom";
83 | this.ZoomMenuItem.Click += new EventHandler(this.ZoomMenuItem_Click);
84 |
85 | //
86 | // ZoomMenuItem
87 | //
88 | this.TrackHeadMenuItem.Name = "TrackHead";
89 | this.TrackHeadMenuItem.Size = new Size(152, 22);
90 | this.TrackHeadMenuItem.Text = "TrackHead";
91 | this.TrackHeadMenuItem.Click += new EventHandler(this.TrackHeadMenuItem_Click);
92 |
93 | TrayIconContextMenu.ResumeLayout(false);
94 | TrayIcon.ContextMenuStrip = TrayIconContextMenu;
95 | }
96 |
97 | private void OnApplicationExit(object sender, EventArgs e)
98 | {
99 | TrayIcon.Visible = false;
100 | }
101 |
102 | private void TrayIcon_DoubleClick(object sender, EventArgs e)
103 | {
104 | TrayIcon.ShowBalloonTip(30000);
105 | }
106 |
107 | private void MirroredMenuItem_Click(object sender, EventArgs e)
108 | {
109 | KinectCamSettigns.Default.Mirrored = !KinectCamSettigns.Default.Mirrored;
110 | }
111 |
112 | private void DesktopMenuItem_Click(object sender, EventArgs e)
113 | {
114 | KinectCamSettigns.Default.Desktop = !KinectCamSettigns.Default.Desktop;
115 | }
116 |
117 | private void ZoomMenuItem_Click(object sender, EventArgs e)
118 | {
119 | KinectCamSettigns.Default.Zoom = !KinectCamSettigns.Default.Zoom;
120 | }
121 |
122 | private void TrackHeadMenuItem_Click(object sender, EventArgs e)
123 | {
124 | KinectCamSettigns.Default.TrackHead = !KinectCamSettigns.Default.TrackHead;
125 | }
126 | public void Exit()
127 | {
128 | TrayIcon.Visible = false;
129 | }
130 | }
131 |
132 | static KinectCamApplicationContext context;
133 | static Thread contexThread;
134 | static Thread refreshThread;
135 | static KinectSensor Sensor;
136 |
137 | static void InitializeSensor()
138 | {
139 | var sensor = Sensor;
140 | if (sensor != null) return;
141 |
142 | try
143 | {
144 | sensor = KinectSensor.GetDefault();
145 | if (sensor == null) return;
146 |
147 | var reader = sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Body); //ColorFrameSource.OpenReader();
148 | reader.MultiSourceFrameArrived += reader_FrameArrived;
149 | sensor.Open();
150 |
151 | Sensor = sensor;
152 |
153 | if (context == null)
154 | {
155 | contexThread = new Thread(() =>
156 | {
157 | context = new KinectCamApplicationContext();
158 | Application.Run(context);
159 | });
160 | refreshThread = new Thread(() =>
161 | {
162 | while (true)
163 | {
164 | Thread.Sleep(250);
165 | Application.DoEvents();
166 | }
167 | });
168 | contexThread.IsBackground = true;
169 | refreshThread.IsBackground = true;
170 | contexThread.SetApartmentState(ApartmentState.STA);
171 | refreshThread.SetApartmentState(ApartmentState.STA);
172 | contexThread.Start();
173 | refreshThread.Start();
174 | }
175 | }
176 | catch
177 | {
178 | Trace.WriteLine("Error of enable the Kinect sensor!");
179 | }
180 | }
181 |
182 | public delegate void InvokeDelegate();
183 |
184 | static void reader_FrameArrived(object sender, MultiSourceFrameArrivedEventArgs e)
185 | {
186 | var reference = e.FrameReference.AcquireFrame();
187 | using (var colorFrame = reference.ColorFrameReference.AcquireFrame())
188 | {
189 | if (colorFrame != null)
190 | {
191 | ColorFrameReady(colorFrame);
192 | }
193 | }
194 | using (var bodyFrame = reference.BodyFrameReference.AcquireFrame())
195 | {
196 | if (bodyFrame != null)
197 | {
198 | var _bodies = new Body[bodyFrame.BodyFrameSource.BodyCount];
199 |
200 | bodyFrame.GetAndRefreshBodyData(_bodies);
201 | _headFound = false;
202 | foreach (var body in _bodies)
203 | {
204 | if (body.IsTracked)
205 | {
206 | Joint head = body.Joints[JointType.Head];
207 |
208 | if (head.TrackingState == TrackingState.NotTracked)
209 | continue;
210 | _headFound = true;
211 | _headPosition = Sensor.CoordinateMapper.MapCameraPointToColorSpace(head.Position);
212 |
213 | }
214 | }
215 | UpdateZoomPosition();
216 | }
217 | }
218 | }
219 | static int SmoothTransitionByStep(int current, int needed, int step = 4)
220 | {
221 |
222 | if (step == 0)
223 | {
224 | return needed;
225 | }
226 | if (current > needed)
227 | {
228 | current -= step;
229 | if (current < needed)
230 | current = needed;
231 | }
232 | else if (current < needed)
233 | {
234 | current += step;
235 | if (current > needed)
236 | current = needed;
237 | }
238 | return current;
239 | }
240 | private static void UpdateZoomPosition()
241 | {
242 | // we should be at 30 fps in this place as Kinect Body are at 30 fps
243 | int NeededZoomedWidthStart = 0;
244 | int NeededZoomedHeightStart;
245 | if (!KinectCamSettigns.Default.TrackHead || !_headFound)
246 | {
247 | NeededZoomedWidthStart = (SensorWidth - ZoomedWidth) / 2;
248 | NeededZoomedHeightStart = (SensorHeight - ZoomedHeight) / 2;
249 | }
250 | else
251 | {
252 | NeededZoomedWidthStart = (int)Math.Min(MaxZoomedWidthStart, Math.Max(0, _headPosition.X - ZoomedWidth / 2));
253 |
254 | NeededZoomedHeightStart = (int)Math.Min(MaxZoomedHeightStart, Math.Max(0, _headPosition.Y - ZoomedHeight / 2));
255 | }
256 |
257 | ZoomedWidthStart = SmoothTransitionByStep(ZoomedWidthStart, NeededZoomedWidthStart, 4);
258 | ZoomedHeightStart = SmoothTransitionByStep(ZoomedHeightStart, NeededZoomedHeightStart, 4);
259 |
260 | ZoomedWidthEnd = ZoomedWidthStart + ZoomedWidth;
261 | ZoomedHeightEnd = ZoomedHeightStart + ZoomedHeight;
262 | ZoomedPointerStart = ZoomedHeightStart * 1920 * 4 + ZoomedWidthStart * 4;
263 | ZoomedPointerEnd = ZoomedHeightEnd * 1920 * 4 + ZoomedWidthEnd * 4;
264 |
265 | }
266 |
267 | static unsafe void ColorFrameReady(ColorFrame frame)
268 | {
269 | if (frame.RawColorImageFormat == ColorImageFormat.Bgra)
270 | {
271 | frame.CopyRawFrameDataToArray(sensorColorFrameData);
272 | }
273 | else
274 | {
275 | frame.CopyConvertedFrameDataToArray(sensorColorFrameData, ColorImageFormat.Bgra);
276 | }
277 | }
278 |
279 | public static void DisposeSensor()
280 | {
281 | try
282 | {
283 | var sensor = Sensor;
284 | if (sensor != null && sensor.IsOpen)
285 | {
286 | sensor.Close();
287 | sensor = null;
288 | Sensor = null;
289 | }
290 |
291 | if (context != null)
292 | {
293 | context.Exit();
294 | context.Dispose();
295 | context = null;
296 |
297 | contexThread.Abort();
298 | refreshThread.Abort();
299 | }
300 | }
301 | catch
302 | {
303 | Trace.WriteLine("Error of disable the Kinect sensor!");
304 | }
305 | }
306 |
307 | static bool _headFound;
308 | static ColorSpacePoint _headPosition;
309 |
310 | public const int SensorWidth = 1920;
311 | public const int SensorHeight = 1080;
312 | public const int ZoomedWidth = 960;
313 | public const int ZoomedHeight = 540;
314 |
315 | public const int DefaultZoomedWidthStart = (SensorWidth - ZoomedWidth) / 2;
316 | public const int DefaultHeightStart = (SensorHeight - ZoomedHeight) / 2;
317 |
318 | public const int MaxZoomedWidthStart = SensorWidth - ZoomedWidth ;
319 | public const int MaxZoomedHeightStart = SensorHeight - (ZoomedHeight+1) ; // +1 to avoid overflow
320 |
321 | public static int ZoomedWidthStart = (SensorWidth - ZoomedWidth) / 2;
322 | public static int ZoomedHeightStart = (SensorHeight - ZoomedHeight) / 2;
323 | public static int ZoomedWidthEnd = ZoomedWidthStart + ZoomedWidth;
324 | public static int ZoomedHeightEnd = ZoomedHeightStart + ZoomedHeight;
325 |
326 |
327 | public static int ZoomedPointerStart = ZoomedHeightStart * 1920 * 4 + ZoomedWidthStart * 4;
328 | public static int ZoomedPointerEnd = ZoomedHeightEnd * 1920 * 4 + ZoomedWidthEnd * 4;
329 | static readonly byte[] sensorColorFrameData = new byte[1920 * 1080 * 4];
330 |
331 | public unsafe static void GenerateFrame(IntPtr _ptr, int length, bool mirrored, bool zoom)
332 | {
333 | byte[] colorFrame = sensorColorFrameData;
334 | void* camData = _ptr.ToPointer();
335 |
336 | try
337 | {
338 | InitializeSensor();
339 |
340 | if (colorFrame != null)
341 | {
342 | int colorFramePointerStart = zoom ? ZoomedPointerStart : 0;
343 | int colorFramePointerEnd = zoom ? ZoomedPointerEnd - 1 : colorFrame.Length - 1;
344 | int width = zoom ? ZoomedWidth : SensorWidth;
345 |
346 | if (!mirrored)
347 | {
348 | fixed (byte* sDataB = &colorFrame[colorFramePointerStart])
349 | fixed (byte* sDataE = &colorFrame[colorFramePointerEnd])
350 | {
351 | byte* pData = (byte*)camData;
352 | byte* sData = (byte*)sDataE;
353 | bool redo = true;
354 |
355 | for (; sData > sDataB;)
356 | {
357 | for (var i = 0; i < width; ++i)
358 | {
359 | var p = sData - 3;
360 | *pData++ = *p++;
361 | *pData++ = *p++;
362 | *pData++ = *p++;
363 | if (zoom)
364 | {
365 | p = sData - 3;
366 | *pData++ = *p++;
367 | *pData++ = *p++;
368 | *pData++ = *p++;
369 | }
370 | sData -= 4;
371 | }
372 | if (zoom)
373 | {
374 | if (redo)
375 | {
376 | sData += width * 4;
377 | }
378 | else
379 | {
380 | sData -= (SensorWidth - ZoomedWidth) * 4;
381 | }
382 | redo = !redo;
383 |
384 | }
385 | }
386 |
387 | }
388 | }
389 | else
390 | {
391 | fixed (byte* sDataB = &colorFrame[colorFramePointerStart])
392 | fixed (byte* sDataE = &colorFrame[colorFramePointerEnd])
393 | {
394 | byte* pData = (byte*)camData;
395 | byte* sData = (byte*)sDataE;
396 |
397 | var sDataBE = sData;
398 | var p = sData;
399 | var r = sData;
400 | bool redo = true;
401 |
402 | while (sData == (sDataBE = sData) &&
403 | sDataB <= (sData -= (width * 4 - 1)))
404 | {
405 |
406 | r = sData;
407 | do
408 | {
409 | p = sData;
410 | *pData++ = *p++;
411 | *pData++ = *p++;
412 | *pData++ = *p++;
413 | if (zoom)
414 | {
415 | p = sData;
416 | *pData++ = *p++;
417 | *pData++ = *p++;
418 | *pData++ = *p++;
419 | }
420 |
421 | }
422 | while ((sData += 4) <= sDataBE);
423 | sData = r - 1;
424 | if (zoom)
425 | {
426 | if (redo)
427 | {
428 | sData += width * 4;
429 | }
430 | else
431 | {
432 | sData -= (SensorWidth - ZoomedWidth) * 4;
433 | }
434 | redo = !redo;
435 |
436 | }
437 | }
438 | }
439 | }
440 | }
441 | }
442 | catch
443 | {
444 | byte* pData = (byte*)camData;
445 | for (int i = 0; i < length; ++i)
446 | *pData++ = 0;
447 | }
448 | }
449 | }
450 | }
451 |
--------------------------------------------------------------------------------
/src/KinectCam/VirtualCam.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using DirectShow;
4 | using DirectShow.BaseClasses;
5 | using Sonic;
6 | using System.Threading;
7 |
8 | namespace KinectCam
9 | {
10 | #region Virtual Cam
11 |
12 | [ComVisible(false)]
13 | public class VirtualCamStream : SourceStream
14 | , IAMStreamControl
15 | , IKsPropertySet
16 | , IAMPushSource
17 | , IAMLatency
18 | , IAMStreamConfig
19 | , IAMBufferNegotiation
20 | {
21 |
22 | #region Constants
23 |
24 | public static HRESULT E_PROP_SET_UNSUPPORTED { get { unchecked { return (HRESULT)0x80070492; } } }
25 | public static HRESULT E_PROP_ID_UNSUPPORTED { get { unchecked { return (HRESULT)0x80070490; } } }
26 |
27 | #endregion
28 |
29 | #region Variables
30 |
31 | protected object m_csPinLock = new object();
32 | protected object m_csTimeLock = new object();
33 | protected long m_rtStart = 0;
34 | protected long m_rtStreamOffset = 0;
35 | protected long m_rtStreamOffsetMax = -1;
36 | protected long m_rtStartAt = -1;
37 | protected long m_rtStopAt = -1;
38 | protected int m_dwStopCookie = 0;
39 | protected int m_dwStartCookie = 0;
40 | protected bool m_bShouldFlush = false;
41 | protected bool m_bStartNotified = false;
42 | protected bool m_bStopNotified = false;
43 | protected AllocatorProperties m_pProperties = null;
44 | protected IReferenceClockImpl m_pClock = null;
45 | // Clock Token
46 | protected int m_dwAdviseToken = 0;
47 | // Clock Semaphore
48 | protected Semaphore m_hSemaphore = null;
49 | // Clock Start time
50 | protected long m_rtClockStart = 0;
51 | // Clock Stop time
52 | protected long m_rtClockStop = 0;
53 | private bool m_isActive;
54 |
55 | #endregion
56 |
57 | #region Constructor
58 |
59 | public VirtualCamStream(string _name, BaseSourceFilter _filter)
60 | : base(_name, _filter)
61 | {
62 | m_mt.majorType = Guid.Empty;
63 |
64 | GetMediaType(0,ref m_mt);
65 | }
66 |
67 | #endregion
68 |
69 | #region Overridden Methods
70 |
71 | public override int SetMediaType(AMMediaType mt)
72 | {
73 | if (mt == null) return E_POINTER;
74 | if (mt.formatPtr == IntPtr.Zero) return VFW_E_INVALIDMEDIATYPE;
75 | HRESULT hr = (HRESULT)CheckMediaType(mt);
76 | if (hr.Failed) return hr;
77 | hr = (HRESULT)base.SetMediaType(mt);
78 | if (hr.Failed) return hr;
79 | if (m_pProperties != null)
80 | {
81 | SuggestAllocatorProperties(m_pProperties);
82 | }
83 | return (m_Filter as VirtualCamFilter).SetMediaType(mt);
84 | }
85 |
86 | public override int CheckMediaType(AMMediaType pmt)
87 | {
88 | return (m_Filter as VirtualCamFilter).CheckMediaType(pmt);
89 | }
90 |
91 | public override int GetMediaType(int iPosition, ref AMMediaType pMediaType)
92 | {
93 | return (m_Filter as VirtualCamFilter).GetMediaType(iPosition,ref pMediaType);
94 | }
95 |
96 | public override int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties pProperties)
97 | {
98 | if (!IsConnected) return VFW_E_NOT_CONNECTED;
99 | AllocatorProperties _actual = new AllocatorProperties();
100 | HRESULT hr = (HRESULT)GetAllocatorProperties(_actual);
101 | if (SUCCEEDED(hr) && _actual.cBuffers <= pProperties.cBuffers && _actual.cbBuffer <= pProperties.cbBuffer && _actual.cbAlign == pProperties.cbAlign)
102 | {
103 | AllocatorProperties Actual = new AllocatorProperties();
104 | hr = (HRESULT)pAlloc.SetProperties(pProperties, Actual);
105 | if (SUCCEEDED(hr))
106 | {
107 | pProperties.cbAlign = Actual.cbAlign;
108 | pProperties.cbBuffer = Actual.cbBuffer;
109 | pProperties.cbPrefix = Actual.cbPrefix;
110 | pProperties.cBuffers = Actual.cBuffers;
111 | }
112 | }
113 | return (m_Filter as VirtualCamFilter).DecideBufferSize(ref pAlloc, ref pProperties);
114 | }
115 |
116 | public override int Active()
117 | {
118 | m_rtStart = 0;
119 | m_bStartNotified = false;
120 | m_bStopNotified = false;
121 | {
122 | lock (m_Filter.FilterLock)
123 | {
124 | m_pClock = m_Filter.Clock;
125 | if (m_pClock.IsValid)
126 | {
127 | m_pClock._AddRef();
128 | }
129 | m_hSemaphore = new Semaphore(0, 0x7FFFFFFF);
130 | m_isActive = true;
131 | }
132 | }
133 | return base.Active();
134 | }
135 |
136 | public override int Inactive()
137 | {
138 | m_isActive = false;
139 | HRESULT hr = (HRESULT)base.Inactive();
140 | if (m_pClock != null)
141 | {
142 | if (m_dwAdviseToken != 0)
143 | {
144 | m_pClock.Unadvise(m_dwAdviseToken);
145 | m_dwAdviseToken = 0;
146 | }
147 | m_pClock._Release();
148 | m_pClock = null;
149 | if (m_hSemaphore != null)
150 | {
151 | m_hSemaphore.Close();
152 | m_hSemaphore = null;
153 | }
154 | }
155 | return hr;
156 | }
157 |
158 | public AMMediaType GetPMT(IMediaSampleImpl _sample)
159 | {
160 | AMMediaType pmt;
161 | if (S_OK == _sample.GetMediaType(out pmt))
162 | {
163 | if (FAILED(SetMediaType(pmt)))
164 | {
165 | ASSERT(false);
166 | _sample.SetMediaType(null);
167 | }
168 | pmt.Free();
169 | }
170 | return pmt;
171 | }
172 |
173 |
174 | public override int FillBuffer(ref IMediaSampleImpl _sample)
175 | {
176 | AMMediaType pmt = GetPMT(_sample);
177 |
178 | long _start, _stop;
179 | HRESULT hr = NOERROR;
180 | long rtLatency;
181 | if (FAILED(GetLatency(out rtLatency)))
182 | {
183 | rtLatency = UNITS / 30;
184 | }
185 | bool bShouldDeliver = false;
186 | do
187 | {
188 | if (m_dwAdviseToken == 0)
189 | {
190 | m_pClock.GetTime(out m_rtClockStart);
191 | if (m_hSemaphore != null)
192 | {
193 | hr = (HRESULT)m_pClock.AdvisePeriodic(m_rtClockStart + rtLatency, rtLatency, m_hSemaphore.Handle, out m_dwAdviseToken);
194 | //hr.Assert();
195 | }
196 | }
197 | else
198 | {
199 | if (m_hSemaphore != null && !m_hSemaphore.WaitOne())
200 | {
201 | ASSERT(FALSE);
202 | }
203 | }
204 | bShouldDeliver = TRUE;
205 | _start = m_rtStart;
206 | _stop = m_rtStart + 1;
207 | _sample.SetTime(_start, _stop);
208 | hr = (HRESULT)(m_Filter as VirtualCamFilter).FillBuffer(ref _sample);
209 | if (FAILED(hr) || S_FALSE == hr) return hr;
210 |
211 | m_pClock.GetTime(out m_rtClockStop);
212 | _sample.GetTime(out _start, out _stop);
213 |
214 | if (rtLatency > 0 && rtLatency * 3 < m_rtClockStop - m_rtClockStart)
215 | {
216 | m_rtClockStop = m_rtClockStart + rtLatency;
217 | }
218 | _stop = _start + (m_rtClockStop - m_rtClockStart);
219 | m_rtStart = _stop;
220 | lock (m_csPinLock)
221 | {
222 | _start -= m_rtStreamOffset;
223 | _stop -= m_rtStreamOffset;
224 | }
225 | _sample.SetTime(_start, _stop);
226 | m_rtClockStart = m_rtClockStop;
227 |
228 | bShouldDeliver = ((_start >= 0) && (_stop >= 0));
229 |
230 | if (bShouldDeliver)
231 | {
232 | lock (m_csPinLock)
233 | if (m_rtStartAt != -1)
234 | {
235 | if (m_rtStartAt > _start)
236 | {
237 | bShouldDeliver = FALSE;
238 | }
239 | else
240 | {
241 | if (m_dwStartCookie != 0 && !m_bStartNotified)
242 | {
243 | m_bStartNotified = TRUE;
244 | hr = (HRESULT)m_Filter.NotifyEvent(EventCode.StreamControlStarted, Marshal.GetIUnknownForObject(this), (IntPtr)m_dwStartCookie);
245 | if (FAILED(hr)) return hr;
246 | }
247 | }
248 | }
249 | if (!bShouldDeliver) continue;
250 | if (m_rtStopAt != -1)
251 | {
252 | if (m_rtStopAt < _start)
253 | {
254 | if (!m_bStopNotified)
255 | {
256 | m_bStopNotified = TRUE;
257 | if (m_dwStopCookie != 0)
258 | {
259 | hr = (HRESULT)m_Filter.NotifyEvent(EventCode.StreamControlStopped, Marshal.GetIUnknownForObject(this), (IntPtr)m_dwStopCookie);
260 | if (FAILED(hr)) return hr;
261 | }
262 | bShouldDeliver = m_bShouldFlush;
263 | }
264 | else
265 | {
266 | bShouldDeliver = FALSE;
267 | }
268 | // EOS
269 | if (!bShouldDeliver) return S_FALSE;
270 | }
271 | }
272 | }
273 | }
274 | while (!bShouldDeliver);
275 |
276 | return NOERROR;
277 | }
278 |
279 | #endregion
280 |
281 | #region IAMBufferNegotiation Members
282 |
283 | public int SuggestAllocatorProperties(AllocatorProperties pprop)
284 | {
285 | if (IsConnected) return VFW_E_ALREADY_CONNECTED;
286 | HRESULT hr = (HRESULT)(m_Filter as VirtualCamFilter).SuggestAllocatorProperties(pprop);
287 | if (FAILED(hr))
288 | {
289 | m_pProperties = null;
290 | return hr;
291 | }
292 | if (m_pProperties == null)
293 | {
294 | m_pProperties = new AllocatorProperties();
295 | (m_Filter as VirtualCamFilter).GetAllocatorProperties(m_pProperties);
296 | }
297 | if (pprop.cbBuffer != -1) m_pProperties.cbBuffer = pprop.cbBuffer;
298 | if (pprop.cbAlign != -1) m_pProperties.cbAlign = pprop.cbAlign;
299 | if (pprop.cbPrefix != -1) m_pProperties.cbPrefix = pprop.cbPrefix;
300 | if (pprop.cBuffers != -1) m_pProperties.cBuffers = pprop.cBuffers;
301 | return NOERROR;
302 | }
303 |
304 | public int GetAllocatorProperties(AllocatorProperties pprop)
305 | {
306 | if (pprop == null) return E_POINTER;
307 | if (m_pProperties != null)
308 | {
309 | pprop.cbAlign = m_pProperties.cbAlign;
310 | pprop.cbBuffer = m_pProperties.cbBuffer;
311 | pprop.cbPrefix = m_pProperties.cbPrefix;
312 | pprop.cBuffers = m_pProperties.cBuffers;
313 | return NOERROR;
314 | }
315 | if (IsConnected)
316 | {
317 | HRESULT hr = (HRESULT)Allocator.GetProperties(pprop);
318 | if (SUCCEEDED(hr) && pprop.cBuffers > 0 && pprop.cbBuffer > 0) return hr;
319 | }
320 | return (m_Filter as VirtualCamFilter).GetAllocatorProperties(pprop);
321 | }
322 |
323 | #endregion
324 |
325 | #region IAMStreamConfig Members
326 |
327 | public int SetFormat(AMMediaType pmt)
328 | {
329 | if (m_Filter.IsActive) return VFW_E_WRONG_STATE;
330 | HRESULT hr;
331 | AMMediaType _newType = new AMMediaType(pmt);
332 | AMMediaType _oldType = new AMMediaType(m_mt);
333 | hr = (HRESULT)CheckMediaType(_newType);
334 | if (FAILED(hr)) return hr;
335 | m_mt.Set(_newType);
336 | if (IsConnected)
337 | {
338 | hr = (HRESULT)Connected.QueryAccept(_newType);
339 | if (SUCCEEDED(hr))
340 | {
341 | hr = (HRESULT)m_Filter.ReconnectPin(this, _newType);
342 | if (SUCCEEDED(hr))
343 | {
344 | hr = (HRESULT)(m_Filter as VirtualCamFilter).SetMediaType(_newType);
345 | }
346 | else
347 | {
348 | m_mt.Set(_oldType);
349 | m_Filter.ReconnectPin(this, _oldType);
350 | }
351 | }
352 | }
353 | else
354 | {
355 | hr = (HRESULT)(m_Filter as VirtualCamFilter).SetMediaType(_newType);
356 | }
357 | return hr;
358 | }
359 |
360 | public int GetFormat(out AMMediaType pmt)
361 | {
362 | pmt = new AMMediaType(m_mt);
363 | return NOERROR;
364 | }
365 |
366 | public int GetNumberOfCapabilities(IntPtr piCount, IntPtr piSize)
367 | {
368 | int iCount;
369 | int iSize;
370 | HRESULT hr = (HRESULT)(m_Filter as VirtualCamFilter).GetNumberOfCapabilities(out iCount, out iSize);
371 | if (hr.Failed) return hr;
372 | if (piCount != IntPtr.Zero)
373 | {
374 | Marshal.WriteInt32(piCount, iCount);
375 | }
376 | if (piSize != IntPtr.Zero)
377 | {
378 | Marshal.WriteInt32(piSize, iSize);
379 | }
380 | return hr;
381 | }
382 |
383 | public int GetStreamCaps(int iIndex, IntPtr ppmt, IntPtr pSCC)
384 | {
385 | AMMediaType pmt;
386 | VideoStreamConfigCaps _caps;
387 | HRESULT hr = (HRESULT)(m_Filter as VirtualCamFilter).GetStreamCaps(iIndex, out pmt, out _caps);
388 | if (hr != S_OK) return hr;
389 |
390 | if (ppmt != IntPtr.Zero)
391 | {
392 | IntPtr _ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(pmt));
393 | Marshal.StructureToPtr(pmt, _ptr, true);
394 | Marshal.WriteIntPtr(ppmt, _ptr);
395 | }
396 | if (pSCC != IntPtr.Zero)
397 | {
398 | Marshal.StructureToPtr(_caps, pSCC, false);
399 | }
400 | return hr;
401 | }
402 |
403 | #endregion
404 |
405 | #region IAMPushSource Members
406 |
407 | public int GetPushSourceFlags(out AMPushSourceFlags pFlags)
408 | {
409 | pFlags = AMPushSourceFlags.None;
410 | return NOERROR;
411 | }
412 |
413 | public int SetPushSourceFlags(AMPushSourceFlags Flags)
414 | {
415 | return E_NOTIMPL;
416 | }
417 |
418 | public int SetStreamOffset(long rtOffset)
419 | {
420 | lock (m_csPinLock)
421 | {
422 | m_rtStreamOffset = rtOffset;
423 | if (m_rtStreamOffset > m_rtStreamOffsetMax) m_rtStreamOffsetMax = m_rtStreamOffset;
424 | }
425 | return NOERROR;
426 | }
427 |
428 | public int GetStreamOffset(out long prtOffset)
429 | {
430 | prtOffset = m_rtStreamOffset;
431 | return NOERROR;
432 | }
433 |
434 | public int GetMaxStreamOffset(out long prtMaxOffset)
435 | {
436 | prtMaxOffset = 0;
437 | if (m_rtStreamOffsetMax == -1)
438 | {
439 | HRESULT hr = (HRESULT)GetLatency(out m_rtStreamOffsetMax);
440 | if (FAILED(hr)) return hr;
441 | if (m_rtStreamOffsetMax < m_rtStreamOffset) m_rtStreamOffsetMax = m_rtStreamOffset;
442 | }
443 | prtMaxOffset = m_rtStreamOffsetMax;
444 | return NOERROR;
445 | }
446 |
447 | public int SetMaxStreamOffset(long rtMaxOffset)
448 | {
449 | if (rtMaxOffset < m_rtStreamOffset) return E_INVALIDARG;
450 | m_rtStreamOffsetMax = rtMaxOffset;
451 | return NOERROR;
452 | }
453 |
454 | #endregion
455 |
456 | #region IKsPropertySet Members
457 |
458 | public int Set(Guid guidPropSet, int dwPropID, IntPtr pInstanceData, int cbInstanceData, IntPtr pPropData, int cbPropData)
459 | {
460 | return E_NOTIMPL;
461 | }
462 |
463 | public int Get(Guid guidPropSet, int dwPropID, IntPtr pInstanceData, int cbInstanceData, IntPtr pPropData, int cbPropData, out int pcbReturned)
464 | {
465 | pcbReturned = Marshal.SizeOf(typeof(Guid));
466 | if (guidPropSet != PropSetID.Pin)
467 | {
468 | return E_PROP_SET_UNSUPPORTED;
469 | }
470 | if (dwPropID != (int)AMPropertyPin.Category)
471 | {
472 | return E_PROP_ID_UNSUPPORTED;
473 | }
474 | if (pPropData == IntPtr.Zero)
475 | {
476 | return NOERROR;
477 | }
478 | if (cbPropData < Marshal.SizeOf(typeof(Guid)))
479 | {
480 | return E_UNEXPECTED;
481 | }
482 | Marshal.StructureToPtr(PinCategory.Capture, pPropData, false);
483 | return NOERROR;
484 | }
485 |
486 | public int QuerySupported(Guid guidPropSet, int dwPropID, out KSPropertySupport pTypeSupport)
487 | {
488 | pTypeSupport = KSPropertySupport.Get;
489 | if (guidPropSet != PropSetID.Pin)
490 | {
491 | return E_PROP_SET_UNSUPPORTED;
492 | }
493 | if (dwPropID != (int)AMPropertyPin.Category)
494 | {
495 | return E_PROP_ID_UNSUPPORTED;
496 | }
497 | return S_OK;
498 | }
499 |
500 | #endregion
501 |
502 | #region IAMStreamControl Members
503 |
504 | public int StartAt(DsLong ptStart, int dwCookie)
505 | {
506 | lock (m_csPinLock)
507 | {
508 | if (ptStart != null && ptStart != MAX_LONG)
509 | {
510 | m_rtStartAt = ptStart;
511 | m_dwStartCookie = dwCookie;
512 | }
513 | else
514 | {
515 | m_rtStartAt = -1;
516 | m_dwStartCookie = 0;
517 | }
518 | }
519 | return NOERROR;
520 | }
521 |
522 | public int StopAt(DsLong ptStop, bool bSendExtra, int dwCookie)
523 | {
524 | lock (m_csPinLock)
525 | {
526 | if (ptStop != null && ptStop != MAX_LONG)
527 | {
528 | m_rtStopAt = ptStop;
529 | m_bShouldFlush = bSendExtra;
530 | m_dwStopCookie = dwCookie;
531 | }
532 | else
533 | {
534 | m_rtStopAt = -1;
535 | m_bShouldFlush = false;
536 | m_dwStopCookie = 0;
537 | }
538 | }
539 | return NOERROR;
540 | }
541 |
542 | public int GetInfo(out AMStreamInfo pInfo)
543 | {
544 | lock(m_csPinLock)
545 | {
546 | pInfo = new AMStreamInfo();
547 | pInfo.dwFlags = AMStreamInfoFlags.None;
548 |
549 | if (m_rtStart < m_rtStartAt)
550 | {
551 | pInfo.dwFlags = pInfo.dwFlags | AMStreamInfoFlags.Discarding;
552 | }
553 | if (m_rtStartAt != -1)
554 | {
555 | pInfo.dwFlags = pInfo.dwFlags | AMStreamInfoFlags.StartDefined;
556 | pInfo.tStart = m_rtStartAt;
557 | pInfo.dwStartCookie = m_dwStartCookie;
558 | }
559 | if (m_rtStopAt != -1)
560 | {
561 | pInfo.dwFlags = pInfo.dwFlags | AMStreamInfoFlags.StopDefined;
562 | pInfo.tStop = m_rtStopAt;
563 | pInfo.dwStopCookie = m_dwStopCookie;
564 | }
565 | if (m_bShouldFlush) pInfo.dwFlags = pInfo.dwFlags | AMStreamInfoFlags.StopSendExtra;
566 | }
567 | return NOERROR;
568 | }
569 |
570 | #endregion
571 |
572 | #region IAMLatency Members
573 |
574 | public int GetLatency(out long prtLatency)
575 | {
576 | return (m_Filter as VirtualCamFilter).GetLatency(out prtLatency);
577 | }
578 |
579 | #endregion
580 | }
581 |
582 |
583 | [ComVisible(true)]
584 | [Guid("E48ECF1A-A5E7-4EB0-8BF7-E15185D66FA4")]
585 | [AMovieSetup(Merit.Normal,AMovieSetup.CLSID_VideoInputDeviceCategory)]
586 | [PropPageSetup(typeof(AboutForm))]
587 | public class VirtualCamFilter : BaseSourceFilter, IAMFilterMiscFlags
588 | {
589 | #region Constants
590 |
591 | private const int c_iDefaultWidth = 1920;
592 | private const int c_iDefaultHeight = 1080;
593 | private const int c_nDefaultBitCount = 24;
594 | private const int c_iDefaultFPS = 30;
595 | private const int c_iFormatsCount = 8;
596 | private const int c_nGranularityW = 160;
597 | private const int c_nGranularityH = 120;
598 | private const int c_nMinWidth = 1920;
599 | private const int c_nMinHeight = 1080;
600 | private const int c_nMaxWidth = c_nMinWidth + c_nGranularityW * (c_iFormatsCount - 1);
601 | private const int c_nMaxHeight = c_nMinHeight + c_nGranularityH * (c_iFormatsCount - 1);
602 | private const int c_nMinFPS = 30;
603 | private const int c_nMaxFPS = 60;
604 |
605 | #endregion
606 |
607 | #region Variables
608 |
609 | protected int m_nWidth = c_iDefaultWidth;
610 | protected int m_nHeight = c_iDefaultHeight;
611 | protected int m_nBitCount = c_nDefaultBitCount;
612 | protected long m_nAvgTimePerFrame = UNITS / c_iDefaultFPS;
613 |
614 | protected IntPtr m_hScreenDC = IntPtr.Zero;
615 | protected IntPtr m_hMemDC = IntPtr.Zero;
616 | protected IntPtr m_hBitmap = IntPtr.Zero;
617 | protected BitmapInfo m_bmi = new BitmapInfo();
618 |
619 | protected int m_nMaxWidth = 0;
620 | protected int m_nMaxHeight = 0;
621 |
622 | #endregion
623 |
624 | #region Constructor
625 |
626 | public VirtualCamFilter()
627 | : base("Kinect Camera V2")
628 | {
629 | m_bmi.bmiHeader = new BitmapInfoHeader();
630 | AddPin(new VirtualCamStream("Capture", this));
631 | }
632 |
633 | #endregion
634 |
635 | #region Overridden Methods
636 |
637 | protected override int OnInitializePins()
638 | {
639 | return NOERROR;
640 | }
641 |
642 | public override int Pause()
643 | {
644 | if (m_State == FilterState.Stopped)
645 | {
646 | m_hScreenDC = CreateDC("DISPLAY", null, null, IntPtr.Zero);
647 | m_nMaxWidth = GetDeviceCaps(m_hScreenDC,8); // HORZRES
648 | m_nMaxHeight = GetDeviceCaps(m_hScreenDC, 10); // VERTRES
649 | m_hMemDC = CreateCompatibleDC(m_hScreenDC);
650 | m_hBitmap = CreateCompatibleBitmap(m_hScreenDC, m_nWidth, Math.Abs(m_nHeight));
651 | }
652 | return base.Pause();
653 | }
654 |
655 | public override int Stop()
656 | {
657 | KinectHelper.DisposeSensor();
658 | int hr = base.Stop();
659 | if (m_hBitmap != IntPtr.Zero)
660 | {
661 | DeleteObject(m_hBitmap);
662 | m_hBitmap = IntPtr.Zero;
663 | }
664 | if (m_hScreenDC != IntPtr.Zero)
665 | {
666 | DeleteDC(m_hScreenDC);
667 | m_hScreenDC = IntPtr.Zero;
668 | }
669 | if (m_hMemDC != IntPtr.Zero)
670 | {
671 | DeleteDC(m_hMemDC);
672 | m_hMemDC = IntPtr.Zero;
673 | }
674 | return hr;
675 | }
676 |
677 | #endregion
678 |
679 | #region Methods
680 |
681 | public int CheckMediaType(AMMediaType pmt)
682 | {
683 | if (pmt == null) return E_POINTER;
684 | if (pmt.formatPtr == IntPtr.Zero) return VFW_E_INVALIDMEDIATYPE;
685 | if (pmt.majorType != MediaType.Video)
686 | {
687 | return VFW_E_INVALIDMEDIATYPE;
688 | }
689 | if (
690 | pmt.subType != MediaSubType.RGB24
691 | && pmt.subType != MediaSubType.RGB32
692 | && pmt.subType != MediaSubType.ARGB32
693 | )
694 | {
695 | return VFW_E_INVALIDMEDIATYPE;
696 | }
697 | BitmapInfoHeader _bmi = pmt;
698 | if (_bmi == null)
699 | {
700 | return E_UNEXPECTED;
701 | }
702 | if (_bmi.Compression != BI_RGB)
703 | {
704 | return VFW_E_TYPE_NOT_ACCEPTED;
705 | }
706 | if (_bmi.BitCount != 24 && _bmi.BitCount != 32)
707 | {
708 | return VFW_E_TYPE_NOT_ACCEPTED;
709 | }
710 | VideoStreamConfigCaps _caps;
711 | GetDefaultCaps(0, out _caps);
712 | if (
713 | _bmi.Width < _caps.MinOutputSize.Width
714 | || _bmi.Width > _caps.MaxOutputSize.Width
715 | )
716 | {
717 | return VFW_E_INVALIDMEDIATYPE;
718 | }
719 | long _rate = 0;
720 | {
721 | VideoInfoHeader _pvi = pmt;
722 | if (_pvi != null)
723 | {
724 | _rate = _pvi.AvgTimePerFrame;
725 | }
726 | }
727 | {
728 | VideoInfoHeader2 _pvi = pmt;
729 | if (_pvi != null)
730 | {
731 | _rate = _pvi.AvgTimePerFrame;
732 | }
733 | }
734 | if (_rate < _caps.MinFrameInterval || _rate > _caps.MaxFrameInterval)
735 | {
736 | return VFW_E_INVALIDMEDIATYPE;
737 | }
738 | return NOERROR;
739 | }
740 |
741 | public int SetMediaType(AMMediaType pmt)
742 | {
743 | lock (m_Lock)
744 | {
745 | if (m_hBitmap != IntPtr.Zero)
746 | {
747 | DeleteObject(m_hBitmap);
748 | m_hBitmap = IntPtr.Zero;
749 | }
750 | BitmapInfoHeader _bmi = pmt;
751 | m_bmi.bmiHeader.BitCount = _bmi.BitCount;
752 | if (_bmi.Height != 0) m_bmi.bmiHeader.Height = _bmi.Height;
753 | if (_bmi.Width > 0) m_bmi.bmiHeader.Width = _bmi.Width;
754 | m_bmi.bmiHeader.Compression = BI_RGB;
755 | m_bmi.bmiHeader.Planes = 1;
756 | m_bmi.bmiHeader.ImageSize = ALIGN16(m_bmi.bmiHeader.Width) * ALIGN16(Math.Abs(m_bmi.bmiHeader.Height)) * m_bmi.bmiHeader.BitCount / 8;
757 | m_nWidth = _bmi.Width;
758 | m_nHeight = _bmi.Height;
759 | m_nBitCount = _bmi.BitCount;
760 |
761 | {
762 | VideoInfoHeader _pvi = pmt;
763 | if (_pvi != null)
764 | {
765 | m_nAvgTimePerFrame = _pvi.AvgTimePerFrame;
766 | }
767 | }
768 | {
769 | VideoInfoHeader2 _pvi = pmt;
770 | if (_pvi != null)
771 | {
772 | m_nAvgTimePerFrame = _pvi.AvgTimePerFrame;
773 | }
774 | }
775 | }
776 | return NOERROR;
777 | }
778 |
779 | public int GetMediaType(int iPosition, ref AMMediaType pMediaType)
780 | {
781 | if (iPosition < 0) return E_INVALIDARG;
782 | VideoStreamConfigCaps _caps;
783 | GetDefaultCaps(0, out _caps);
784 |
785 | int nWidth = 0;
786 | int nHeight = 0;
787 |
788 | if (iPosition == 0)
789 | {
790 | if (Pins.Count > 0 && Pins[0].CurrentMediaType.majorType == MediaType.Video)
791 | {
792 | pMediaType.Set(Pins[0].CurrentMediaType);
793 | return NOERROR;
794 | }
795 | nWidth = _caps.InputSize.Width;
796 | nHeight = _caps.InputSize.Height;
797 | }
798 | else
799 | {
800 | iPosition--;
801 | nWidth = _caps.MinOutputSize.Width + _caps.OutputGranularityX * iPosition;
802 | nHeight = _caps.MinOutputSize.Height + _caps.OutputGranularityY * iPosition;
803 | if (nWidth > _caps.MaxOutputSize.Width || nHeight > _caps.MaxOutputSize.Height)
804 | {
805 | return VFW_S_NO_MORE_ITEMS;
806 | }
807 | }
808 |
809 | pMediaType.majorType = DirectShow.MediaType.Video;
810 | pMediaType.formatType = DirectShow.FormatType.VideoInfo;
811 |
812 | VideoInfoHeader vih = new VideoInfoHeader();
813 | vih.AvgTimePerFrame = m_nAvgTimePerFrame;
814 | vih.BmiHeader.Compression = BI_RGB;
815 | vih.BmiHeader.BitCount = (short)m_nBitCount;
816 | vih.BmiHeader.Width = nWidth;
817 | vih.BmiHeader.Height = nHeight;
818 | vih.BmiHeader.Planes = 1;
819 | vih.BmiHeader.ImageSize = vih.BmiHeader.Width * Math.Abs(vih.BmiHeader.Height) * vih.BmiHeader.BitCount / 8;
820 |
821 | if (vih.BmiHeader.BitCount == 32)
822 | {
823 | pMediaType.subType = DirectShow.MediaSubType.RGB32;
824 | }
825 | if (vih.BmiHeader.BitCount == 24)
826 | {
827 | pMediaType.subType = DirectShow.MediaSubType.RGB24;
828 | }
829 | AMMediaType.SetFormat(ref pMediaType, ref vih);
830 | pMediaType.fixedSizeSamples = true;
831 | pMediaType.sampleSize = vih.BmiHeader.ImageSize;
832 |
833 | return NOERROR;
834 | }
835 |
836 | public int DecideBufferSize(ref IMemAllocatorImpl pAlloc, ref AllocatorProperties prop)
837 | {
838 | AllocatorProperties _actual = new AllocatorProperties();
839 |
840 | BitmapInfoHeader _bmi = (BitmapInfoHeader)Pins[0].CurrentMediaType;
841 | prop.cbBuffer = _bmi.GetBitmapSize();
842 |
843 | if (prop.cbBuffer < _bmi.ImageSize)
844 | {
845 | prop.cbBuffer = _bmi.ImageSize;
846 | }
847 | if (prop.cbBuffer < m_bmi.bmiHeader.ImageSize)
848 | {
849 | prop.cbBuffer = m_bmi.bmiHeader.ImageSize;
850 | }
851 |
852 | prop.cBuffers = 1;
853 | prop.cbAlign = 1;
854 | prop.cbPrefix = 0;
855 | int hr = pAlloc.SetProperties(prop, _actual);
856 | return hr;
857 | }
858 |
859 | public unsafe int FillBuffer(ref IMediaSampleImpl _sample)
860 | {
861 | IntPtr _ptr;
862 | _sample.GetPointer(out _ptr);
863 | int length = _sample.GetSize();
864 |
865 | if (!KinectCamSettigns.Default.Desktop)
866 | {
867 | KinectHelper.GenerateFrame(_ptr, length, KinectCamSettigns.Default.Mirrored,KinectCamSettigns.Default.Zoom);
868 | }
869 | else
870 | {
871 | if (m_hBitmap == IntPtr.Zero)
872 | {
873 | m_hBitmap = CreateCompatibleBitmap(m_hScreenDC, m_nWidth, Math.Abs(m_nHeight));
874 | }
875 | IntPtr hOldBitmap = SelectObject(m_hMemDC, m_hBitmap);
876 | StretchBlt(m_hMemDC, 0, 0, m_nWidth, Math.Abs(m_nHeight), m_hScreenDC, 0, 0, m_nMaxWidth, m_nMaxHeight, TernaryRasterOperations.SRCCOPY);
877 | SelectObject(m_hMemDC, hOldBitmap);
878 | GetDIBits(m_hMemDC, m_hBitmap, 0, (uint)Math.Abs(m_nHeight), _ptr, ref m_bmi, 0);
879 | }
880 |
881 | _sample.SetActualDataLength(_sample.GetSize());
882 | _sample.SetSyncPoint(true);
883 |
884 | return NOERROR;
885 | }
886 |
887 | public int GetLatency(out long prtLatency)
888 | {
889 | prtLatency = UNITS / 30;
890 | AMMediaType mt = Pins[0].CurrentMediaType;
891 | if (mt.majorType == MediaType.Video)
892 | {
893 | {
894 | VideoInfoHeader _pvi = mt;
895 | if (_pvi != null)
896 | {
897 | prtLatency = _pvi.AvgTimePerFrame;
898 | }
899 | }
900 | {
901 | VideoInfoHeader2 _pvi = mt;
902 | if (_pvi != null)
903 | {
904 | prtLatency = _pvi.AvgTimePerFrame;
905 | }
906 | }
907 | }
908 | return NOERROR;
909 | }
910 |
911 | public int GetNumberOfCapabilities(out int iCount, out int iSize)
912 | {
913 | iCount = 0;
914 | AMMediaType mt = new AMMediaType();
915 | while (GetMediaType(iCount, ref mt) == S_OK) { mt.Free(); iCount++; };
916 | iSize = Marshal.SizeOf(typeof(VideoStreamConfigCaps));
917 | return NOERROR;
918 | }
919 |
920 | public int GetStreamCaps(int iIndex,out AMMediaType ppmt, out VideoStreamConfigCaps _caps)
921 | {
922 | ppmt = null;
923 | _caps = null;
924 | if (iIndex < 0) return E_INVALIDARG;
925 |
926 | ppmt = new AMMediaType();
927 | HRESULT hr = (HRESULT)GetMediaType(iIndex, ref ppmt);
928 | if (FAILED(hr)) return hr;
929 | if (hr == VFW_S_NO_MORE_ITEMS) return S_FALSE;
930 | hr = (HRESULT)GetDefaultCaps(iIndex, out _caps);
931 | return hr;
932 | }
933 |
934 | public int SuggestAllocatorProperties(AllocatorProperties pprop)
935 | {
936 | AllocatorProperties _properties = new AllocatorProperties();
937 | HRESULT hr = (HRESULT)GetAllocatorProperties(_properties);
938 | if (FAILED(hr)) return hr;
939 | if (pprop.cbBuffer != -1)
940 | {
941 | if (pprop.cbBuffer < _properties.cbBuffer) return E_FAIL;
942 | }
943 | if (pprop.cbAlign != -1 && pprop.cbAlign != _properties.cbAlign) return E_FAIL;
944 | if (pprop.cbPrefix != -1 && pprop.cbPrefix != _properties.cbPrefix) return E_FAIL;
945 | if (pprop.cBuffers != -1 && pprop.cBuffers < 1) return E_FAIL;
946 | return NOERROR;
947 | }
948 |
949 | public int GetAllocatorProperties(AllocatorProperties pprop)
950 | {
951 | AMMediaType mt = Pins[0].CurrentMediaType;
952 | if (mt.majorType == MediaType.Video)
953 | {
954 | int lSize = mt.sampleSize;
955 | BitmapInfoHeader _bmi = mt;
956 | if (_bmi != null)
957 | {
958 | if (lSize < _bmi.GetBitmapSize())
959 | {
960 | lSize = _bmi.GetBitmapSize();
961 | }
962 | if (lSize < _bmi.ImageSize)
963 | {
964 | lSize = _bmi.ImageSize;
965 | }
966 | }
967 | pprop.cbBuffer = lSize;
968 | pprop.cBuffers = 1;
969 | pprop.cbAlign = 1;
970 | pprop.cbPrefix = 0;
971 |
972 | }
973 | return NOERROR;
974 | }
975 |
976 | public int GetDefaultCaps(int nIndex, out VideoStreamConfigCaps _caps)
977 | {
978 | _caps = new VideoStreamConfigCaps();
979 |
980 | _caps.guid = FormatType.VideoInfo;
981 | _caps.VideoStandard = AnalogVideoStandard.None;
982 | _caps.InputSize.Width = c_iDefaultWidth;
983 | _caps.InputSize.Height = c_iDefaultHeight;
984 | _caps.MinCroppingSize.Width = c_nMinWidth;
985 | _caps.MinCroppingSize.Height = c_nMinHeight;
986 |
987 | _caps.MaxCroppingSize.Width = c_nMaxWidth;
988 | _caps.MaxCroppingSize.Height = c_nMaxHeight;
989 | _caps.CropGranularityX = c_nGranularityW;
990 | _caps.CropGranularityY = c_nGranularityH;
991 | _caps.CropAlignX = 0;
992 | _caps.CropAlignY = 0;
993 |
994 | _caps.MinOutputSize.Width = _caps.MinCroppingSize.Width;
995 | _caps.MinOutputSize.Height = _caps.MinCroppingSize.Height;
996 | _caps.MaxOutputSize.Width = _caps.MaxCroppingSize.Width;
997 | _caps.MaxOutputSize.Height = _caps.MaxCroppingSize.Height;
998 | _caps.OutputGranularityX = _caps.CropGranularityX;
999 | _caps.OutputGranularityY = _caps.CropGranularityY;
1000 | _caps.StretchTapsX = 0;
1001 | _caps.StretchTapsY = 0;
1002 | _caps.ShrinkTapsX = 0;
1003 | _caps.ShrinkTapsY = 0;
1004 | _caps.MinFrameInterval = UNITS / c_nMaxFPS;
1005 | _caps.MaxFrameInterval = UNITS / c_nMinFPS;
1006 | _caps.MinBitsPerSecond = (_caps.MinOutputSize.Width * _caps.MinOutputSize.Height * c_nDefaultBitCount) * c_nMinFPS;
1007 | _caps.MaxBitsPerSecond = (_caps.MaxOutputSize.Width * _caps.MaxOutputSize.Height * c_nDefaultBitCount) * c_nMaxFPS;
1008 |
1009 | return NOERROR;
1010 | }
1011 |
1012 | #endregion
1013 |
1014 | #region IAMFilterMiscFlags Members
1015 |
1016 | public int GetMiscFlags()
1017 | {
1018 | return (int)AMFilterMiscFlags.IsSource;
1019 | }
1020 |
1021 | #endregion
1022 |
1023 | #region API
1024 |
1025 | [StructLayout(LayoutKind.Sequential)]
1026 | protected struct BitmapInfo
1027 | {
1028 | public BitmapInfoHeader bmiHeader;
1029 | public int[] bmiColors;
1030 | }
1031 |
1032 | private enum TernaryRasterOperations : uint
1033 | {
1034 | SRCCOPY = 0x00CC0020,
1035 | SRCPAINT = 0x00EE0086,
1036 | SRCAND = 0x008800C6,
1037 | SRCINVERT = 0x00660046,
1038 | SRCERASE = 0x00440328,
1039 | NOTSRCCOPY = 0x00330008,
1040 | NOTSRCERASE = 0x001100A6,
1041 | MERGECOPY = 0x00C000CA,
1042 | MERGEPAINT = 0x00BB0226,
1043 | PATCOPY = 0x00F00021,
1044 | PATPAINT = 0x00FB0A09,
1045 | PATINVERT = 0x005A0049,
1046 | DSTINVERT = 0x00550009,
1047 | BLACKNESS = 0x00000042,
1048 | WHITENESS = 0x00FF0062,
1049 | CAPTUREBLT = 0x40000000
1050 | }
1051 |
1052 | [DllImport("gdi32.dll")]
1053 | private static extern IntPtr CreateDC(string lpszDriver, string lpszDevice, string lpszOutput, IntPtr lpInitData);
1054 |
1055 | [DllImport("gdi32.dll", SetLastError = true)]
1056 | private static extern IntPtr CreateCompatibleDC(IntPtr hdc);
1057 |
1058 | [DllImport("gdi32.dll")]
1059 | private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
1060 |
1061 | [DllImport("gdi32.dll", ExactSpelling = true, PreserveSig = true, SetLastError = true)]
1062 | private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
1063 |
1064 | [DllImport("gdi32.dll")]
1065 | private static extern bool DeleteObject(IntPtr hObject);
1066 |
1067 | [DllImport("gdi32.dll")]
1068 | private static extern bool DeleteDC(IntPtr hdc);
1069 |
1070 | [DllImport("gdi32.dll")]
1071 | private static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest, int nYOriginDest,
1072 | int nWidthDest, int nHeightDest,
1073 | IntPtr hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
1074 | TernaryRasterOperations dwRop);
1075 |
1076 | [DllImport("gdi32.dll")]
1077 | private static extern int GetDIBits(IntPtr hdc, IntPtr hbmp, uint uStartScan,
1078 | uint cScanLines, [Out] IntPtr lpvBits, ref BitmapInfo lpbmi, uint uUsage);
1079 |
1080 | [DllImport("gdi32.dll")]
1081 | private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
1082 |
1083 | #endregion
1084 | }
1085 |
1086 | #endregion
1087 |
1088 | }
1089 |
--------------------------------------------------------------------------------