├── 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 | --------------------------------------------------------------------------------