Full Code of dajuric/dot-imaging for AI

master 27d39aad31a5 cached
91 files
432.8 KB
103.7k tokens
538 symbols
1 requests
Download .txt
Showing preview only (461K chars total). Download the full file or copy to clipboard to get everything.
Repository: dajuric/dot-imaging
Branch: master
Commit: 27d39aad31a5
Files: 91
Total size: 432.8 KB

Directory structure:
gitextract_pvk6qki_/

├── .gitignore
├── Deploy/
│   ├── Licence.txt
│   ├── Logo/
│   │   └── DotImaging.pptx
│   └── Nuget/
│       └── Push.ps1
├── Directory.Build.props
├── DotImaging.sln
├── README.md
├── Samples/
│   ├── Sample.Basic/
│   │   ├── Program.cs
│   │   └── Sample.Basic.csproj
│   ├── Sample.Capture/
│   │   ├── Program.cs
│   │   └── Sample.Capture.csproj
│   ├── Sample.CaptureAndRecord/
│   │   ├── Program.cs
│   │   └── Sample.CaptureAndRecord.csproj
│   ├── Sample.ImageExtractor/
│   │   ├── Program.cs
│   │   └── Sample.ImageExtractor.csproj
│   ├── Sample.Interop/
│   │   ├── Program.cs
│   │   └── Sample.Interop.csproj
│   ├── Sample.MultipleCameraCapture/
│   │   ├── Program.cs
│   │   └── Sample.MultipleCameraCapture.csproj
│   ├── Sample.UI/
│   │   ├── Program.cs
│   │   └── Sample.UI.csproj
│   └── Sample.VideoStreaming/
│       ├── Program.cs
│       └── Sample.VideoStreaming.csproj
└── Source/
    ├── BitmapInterop/
    │   ├── .nuSpec/
    │   │   └── readmeImage.Bitmap.txt
    │   ├── BmpExtensions/
    │   │   ├── BitmapConversion.cs
    │   │   ├── BmpIO.cs
    │   │   └── ColorConversion.cs
    │   └── Image.BitmapInterop.csproj
    ├── IO/
    │   ├── .nuSpec/
    │   │   └── readmeIO.txt
    │   ├── Base/
    │   │   ├── Abstract/
    │   │   │   ├── ImageStream.cs
    │   │   │   ├── ImageStreamReader.cs
    │   │   │   └── ImageStreamWriter.cs
    │   │   └── CvInvoke.cs
    │   ├── IO.csproj
    │   ├── ImageIO.cs
    │   ├── Readers/
    │   │   ├── CameraCapture.cs
    │   │   ├── FileCapture.cs
    │   │   ├── ImageDirectoryCapture.cs
    │   │   └── VideoCaptureBase.cs
    │   ├── Utilities/
    │   │   ├── NaturalSortComparer.cs
    │   │   └── PathExtensions.cs
    │   ├── Writers/
    │   │   ├── ImageWriterExtension.cs
    │   │   └── VideoWriter.cs
    │   └── runtimes/
    │       └── ubuntu.16.04-x64/
    │           ├── libopencv_core.so.2.4
    │           ├── libopencv_highgui.so.2.4
    │           └── libopencv_video.so.2.4
    ├── IO.Web/
    │   ├── .nuSpec/
    │   │   └── readmeIO.Web.txt
    │   ├── IO.Web.csproj
    │   ├── NamedPipeExtensions.cs
    │   └── WebImageExtensions.cs
    ├── Image/
    │   ├── .nuSpec/
    │   │   └── readmeImage.txt
    │   ├── ColorTypeConversions/
    │   │   ├── ColorInfo.cs
    │   │   ├── ColorSpaces/
    │   │   │   ├── Bgr.cs
    │   │   │   ├── Bgra.cs
    │   │   │   ├── Gray.cs
    │   │   │   ├── Hsv.cs
    │   │   │   ├── IColor.cs
    │   │   │   └── Rgb.cs
    │   │   └── Converters/
    │   │       └── ColorConversionExtensions.cs
    │   ├── Extensions/
    │   │   ├── BasicExtensions.cs
    │   │   ├── ChannelMerger.cs
    │   │   ├── ChannelSplitter.cs
    │   │   ├── Convert.cs
    │   │   ├── Copy.cs
    │   │   ├── ImageFlipping.cs
    │   │   └── SpatialConvolution.cs
    │   ├── Image.csproj
    │   ├── Interop/
    │   │   ├── CvMat.cs
    │   │   └── IplImage.cs
    │   ├── Linq/
    │   │   └── ImagingLinq.cs
    │   ├── ParallelLauncher.cs
    │   ├── Slice2D.cs
    │   └── Unmanaged/
    │       ├── IImage.cs
    │       └── Image'1.cs
    ├── Primitives2D/
    │   ├── Box2D/
    │   │   └── Box2D.cs
    │   ├── Circle/
    │   │   ├── Circle.cs
    │   │   └── CircleF.cs
    │   ├── Ellipse/
    │   │   └── Ellipse.cs
    │   ├── Point/
    │   │   ├── Point'1.cs
    │   │   └── PointExtensions.cs
    │   ├── Primitives2D.csproj
    │   ├── Rectangle/
    │   │   └── RectangleExtensions.cs
    │   └── Size/
    │       └── SizeExtensions.cs
    └── UI.Image/
        ├── .nuSpec/
        │   └── readmeUI.Image.txt
        ├── Base/
        │   ├── CvCoreInvoke.cs
        │   └── CvInvoke.cs
        ├── Drawing.cs
        ├── ImageUI.cs
        ├── UI.Image.csproj
        └── runtimes/
            └── ubuntu.16.04-x64/
                ├── libopencv_core.so.2.4
                └── libopencv_highgui.so.2.4

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
build/
bld/
[Bb]in/
[Oo]bj/

# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
!packages/*/build/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

#NUNIT
*.VisualState.xml
TestResult.xml

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding addin-in
.JustCode

# TeamCity is a build add-in
# NuGet
*.nuget.props
*.nuget.targets

**/packages/*
!**/packages/build/

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# Build results
[Dd]ebug/
[Rr]elease/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
.vs/

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
/Deploy/Nuget/NuGet.exe


================================================
FILE: Deploy/Licence.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: Deploy/Nuget/Push.ps1
================================================
#--references: 
#  list files: https://medium.com/@victorleungtw/replace-text-in-xml-files-with-powershell-504d3e37a058

timeout /T 5

Write-Host
Write-Host Pushing packages:
$files = @(Get-ChildItem *.nupkg -Recurse)
foreach($f in $files)
{
   Write-Host $f
   $cmd = './nuget push "$f" -source https://www.nuget.org/api/v2/package'
   iex $cmd
}

Write-Host
#pause

================================================
FILE: Directory.Build.props
================================================
<Project>
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <LangVersion>preview</LangVersion>
	<OutputPath>bin\</OutputPath>
	<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
  </PropertyGroup>
</Project>

================================================
FILE: DotImaging.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{80058A54-6223-480C-AA19-F99E7AE593F3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{05BDC895-7F7B-4B6F-8D69-E7916837092D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Deploy", "Deploy", "{80FC5EA1-3478-4E7F-8B05-190DF6750EA4}"
	ProjectSection(SolutionItems) = preProject
		Deploy\Licence.txt = Deploy\Licence.txt
	EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Logo", "Logo", "{817B040E-5F27-4ACD-B1E4-F46452668A0E}"
	ProjectSection(SolutionItems) = preProject
		Deploy\Logo\DotImaging.pptx = Deploy\Logo\DotImaging.pptx
		Deploy\Logo\logo-big.png = Deploy\Logo\logo-big.png
		Deploy\Logo\logo-small.png = Deploy\Logo\logo-small.png
	EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Image.BitmapInterop", "Source\BitmapInterop\Image.BitmapInterop.csproj", "{CE222A84-B03B-4053-8BA4-F237063382F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Image", "Source\Image\Image.csproj", "{3CF8F155-3DA1-4529-9B28-D409E86ED4E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IO", "Source\IO\IO.csproj", "{ED70A44E-9443-4A28-9B95-31299F8B2D08}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IO.Web", "Source\IO.Web\IO.Web.csproj", "{B8404D66-B64E-43E0-9653-35FC6782072F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.VideoStreaming", "Samples\Sample.VideoStreaming\Sample.VideoStreaming.csproj", "{CB088D8A-3438-4DB9-87C2-99425FE27F07}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Basic", "Samples\Sample.Basic\Sample.Basic.csproj", "{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Interop", "Samples\Sample.Interop\Sample.Interop.csproj", "{E4ED626D-359B-493C-A72E-3738A5353D1B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Capture", "Samples\Sample.Capture\Sample.Capture.csproj", "{D0C18418-5282-4BA8-ABF7-CC2A9A179517}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.CaptureAndRecord", "Samples\Sample.CaptureAndRecord\Sample.CaptureAndRecord.csproj", "{867ED0BD-FBFB-4C0C-A34B-D71361874AA0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.ImageExtractor", "Samples\Sample.ImageExtractor\Sample.ImageExtractor.csproj", "{55FF1668-9501-4007-84D8-26EF860F0D0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MultipleCameraCapture", "Samples\Sample.MultipleCameraCapture\Sample.MultipleCameraCapture.csproj", "{C30A145E-02FB-49B4-8F3E-6673AF9D121A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGet", "NuGet", "{44744CCA-2769-4607-AC90-78B6A11A2E77}"
	ProjectSection(SolutionItems) = preProject
		Deploy\Nuget\Push.ps1 = Deploy\Nuget\Push.ps1
		Deploy\Nuget\UpdatePackageVersion.ps1 = Deploy\Nuget\UpdatePackageVersion.ps1
	EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UI.Image", "Source\UI.Image\UI.Image.csproj", "{F021F056-59F7-4C49-9F0F-3BE6721F920F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7C2B92C2-DD93-47F5-8ADA-BF21086EDCDD}"
	ProjectSection(SolutionItems) = preProject
		Directory.Build.props = Directory.Build.props
		README.md = README.md
	EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Primitives2D", "Source\Primitives2D\Primitives2D.csproj", "{CF955F14-669D-4802-A3A3-0CDA7601205E}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|x64 = Debug|x64
		Release|x64 = Release|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{CE222A84-B03B-4053-8BA4-F237063382F2}.Debug|x64.ActiveCfg = Debug|Any CPU
		{CE222A84-B03B-4053-8BA4-F237063382F2}.Debug|x64.Build.0 = Debug|Any CPU
		{CE222A84-B03B-4053-8BA4-F237063382F2}.Release|x64.ActiveCfg = Release|Any CPU
		{CE222A84-B03B-4053-8BA4-F237063382F2}.Release|x64.Build.0 = Release|Any CPU
		{3CF8F155-3DA1-4529-9B28-D409E86ED4E2}.Debug|x64.ActiveCfg = Debug|Any CPU
		{3CF8F155-3DA1-4529-9B28-D409E86ED4E2}.Debug|x64.Build.0 = Debug|Any CPU
		{3CF8F155-3DA1-4529-9B28-D409E86ED4E2}.Release|x64.ActiveCfg = Release|Any CPU
		{3CF8F155-3DA1-4529-9B28-D409E86ED4E2}.Release|x64.Build.0 = Release|Any CPU
		{ED70A44E-9443-4A28-9B95-31299F8B2D08}.Debug|x64.ActiveCfg = Debug|x64
		{ED70A44E-9443-4A28-9B95-31299F8B2D08}.Debug|x64.Build.0 = Debug|x64
		{ED70A44E-9443-4A28-9B95-31299F8B2D08}.Release|x64.ActiveCfg = Release|x64
		{ED70A44E-9443-4A28-9B95-31299F8B2D08}.Release|x64.Build.0 = Release|x64
		{B8404D66-B64E-43E0-9653-35FC6782072F}.Debug|x64.ActiveCfg = Debug|Any CPU
		{B8404D66-B64E-43E0-9653-35FC6782072F}.Debug|x64.Build.0 = Debug|Any CPU
		{B8404D66-B64E-43E0-9653-35FC6782072F}.Release|x64.ActiveCfg = Release|Any CPU
		{B8404D66-B64E-43E0-9653-35FC6782072F}.Release|x64.Build.0 = Release|Any CPU
		{CB088D8A-3438-4DB9-87C2-99425FE27F07}.Debug|x64.ActiveCfg = Debug|x64
		{CB088D8A-3438-4DB9-87C2-99425FE27F07}.Debug|x64.Build.0 = Debug|x64
		{CB088D8A-3438-4DB9-87C2-99425FE27F07}.Release|x64.ActiveCfg = Release|x64
		{CB088D8A-3438-4DB9-87C2-99425FE27F07}.Release|x64.Build.0 = Release|x64
		{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A}.Debug|x64.ActiveCfg = Debug|x64
		{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A}.Debug|x64.Build.0 = Debug|x64
		{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A}.Release|x64.ActiveCfg = Release|x64
		{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A}.Release|x64.Build.0 = Release|x64
		{E4ED626D-359B-493C-A72E-3738A5353D1B}.Debug|x64.ActiveCfg = Debug|x64
		{E4ED626D-359B-493C-A72E-3738A5353D1B}.Debug|x64.Build.0 = Debug|x64
		{E4ED626D-359B-493C-A72E-3738A5353D1B}.Release|x64.ActiveCfg = Release|x64
		{E4ED626D-359B-493C-A72E-3738A5353D1B}.Release|x64.Build.0 = Release|x64
		{D0C18418-5282-4BA8-ABF7-CC2A9A179517}.Debug|x64.ActiveCfg = Debug|x64
		{D0C18418-5282-4BA8-ABF7-CC2A9A179517}.Debug|x64.Build.0 = Debug|x64
		{D0C18418-5282-4BA8-ABF7-CC2A9A179517}.Release|x64.ActiveCfg = Release|x64
		{D0C18418-5282-4BA8-ABF7-CC2A9A179517}.Release|x64.Build.0 = Release|x64
		{867ED0BD-FBFB-4C0C-A34B-D71361874AA0}.Debug|x64.ActiveCfg = Debug|x64
		{867ED0BD-FBFB-4C0C-A34B-D71361874AA0}.Debug|x64.Build.0 = Debug|x64
		{867ED0BD-FBFB-4C0C-A34B-D71361874AA0}.Release|x64.ActiveCfg = Release|x64
		{867ED0BD-FBFB-4C0C-A34B-D71361874AA0}.Release|x64.Build.0 = Release|x64
		{55FF1668-9501-4007-84D8-26EF860F0D0D}.Debug|x64.ActiveCfg = Debug|x64
		{55FF1668-9501-4007-84D8-26EF860F0D0D}.Debug|x64.Build.0 = Debug|x64
		{55FF1668-9501-4007-84D8-26EF860F0D0D}.Release|x64.ActiveCfg = Release|x64
		{55FF1668-9501-4007-84D8-26EF860F0D0D}.Release|x64.Build.0 = Release|x64
		{C30A145E-02FB-49B4-8F3E-6673AF9D121A}.Debug|x64.ActiveCfg = Debug|x64
		{C30A145E-02FB-49B4-8F3E-6673AF9D121A}.Debug|x64.Build.0 = Debug|x64
		{C30A145E-02FB-49B4-8F3E-6673AF9D121A}.Release|x64.ActiveCfg = Release|x64
		{C30A145E-02FB-49B4-8F3E-6673AF9D121A}.Release|x64.Build.0 = Release|x64
		{F021F056-59F7-4C49-9F0F-3BE6721F920F}.Debug|x64.ActiveCfg = Debug|x64
		{F021F056-59F7-4C49-9F0F-3BE6721F920F}.Debug|x64.Build.0 = Debug|x64
		{F021F056-59F7-4C49-9F0F-3BE6721F920F}.Release|x64.ActiveCfg = Release|x64
		{F021F056-59F7-4C49-9F0F-3BE6721F920F}.Release|x64.Build.0 = Release|x64
		{CF955F14-669D-4802-A3A3-0CDA7601205E}.Debug|x64.ActiveCfg = Debug|Any CPU
		{CF955F14-669D-4802-A3A3-0CDA7601205E}.Debug|x64.Build.0 = Debug|Any CPU
		{CF955F14-669D-4802-A3A3-0CDA7601205E}.Release|x64.ActiveCfg = Release|Any CPU
		{CF955F14-669D-4802-A3A3-0CDA7601205E}.Release|x64.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(NestedProjects) = preSolution
		{817B040E-5F27-4ACD-B1E4-F46452668A0E} = {80FC5EA1-3478-4E7F-8B05-190DF6750EA4}
		{CE222A84-B03B-4053-8BA4-F237063382F2} = {80058A54-6223-480C-AA19-F99E7AE593F3}
		{3CF8F155-3DA1-4529-9B28-D409E86ED4E2} = {80058A54-6223-480C-AA19-F99E7AE593F3}
		{ED70A44E-9443-4A28-9B95-31299F8B2D08} = {80058A54-6223-480C-AA19-F99E7AE593F3}
		{B8404D66-B64E-43E0-9653-35FC6782072F} = {80058A54-6223-480C-AA19-F99E7AE593F3}
		{CB088D8A-3438-4DB9-87C2-99425FE27F07} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{5F5FE08B-37C1-4C62-BB1A-DFFF61B3516A} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{E4ED626D-359B-493C-A72E-3738A5353D1B} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{D0C18418-5282-4BA8-ABF7-CC2A9A179517} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{867ED0BD-FBFB-4C0C-A34B-D71361874AA0} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{55FF1668-9501-4007-84D8-26EF860F0D0D} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{C30A145E-02FB-49B4-8F3E-6673AF9D121A} = {05BDC895-7F7B-4B6F-8D69-E7916837092D}
		{44744CCA-2769-4607-AC90-78B6A11A2E77} = {80FC5EA1-3478-4E7F-8B05-190DF6750EA4}
		{F021F056-59F7-4C49-9F0F-3BE6721F920F} = {80058A54-6223-480C-AA19-F99E7AE593F3}
		{CF955F14-669D-4802-A3A3-0CDA7601205E} = {80058A54-6223-480C-AA19-F99E7AE593F3}
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {DEAC2BC6-C697-4361-9909-CF7055FE9B05}
	EndGlobalSection
EndGlobal


================================================
FILE: README.md
================================================
<p align="center">
    <a href="https://www.nuget.org/profiles/dajuric"> <img src="Deploy/Logo/logo-big.png" alt="DotImaging logo" width="120" align="center"> </a>
</p>

<p align="center">
    <a href="https://www.nuget.org/profiles/dajuric"> <img src="https://img.shields.io/badge/NuGet-v5.2.0-blue.svg?style=flat-square" alt="NuGet packages version"/>  </a>
</p>

**DotImaging** - .NET array as imaging object  
The framework sets focus on .NET native array as primary imaging object, offers extensibility support via extensions, and provides unified platform-abstract imaging IO API. 

## News
+ 5.2.0 version came out (19/02/2019)
+ Image enchacement library for DotImaging: <a href="https://github.com/dajuric/dot-devignetting">DotDevignetting</a>!

## So why DotImaging ?

+ Image as native .NET 2D array 
+ portable* 
+ lightweight
+ extensions, extensions, extensions....

*IO and Drawing assemlies depend on OpenCV

## Libraries / NuGet packages


###### Core

+ <a href="https://www.nuget.org/packages/DotImaging.Image"> 
    <img src="https://img.shields.io/badge/DotImaging-Image-red.svg?style=flat-square" alt="DotImaging.Image"/>  
  </a> 
  .NET image array extensions. Color and depth conversions. Slim unmanaged structure for fast pixel manipulation.

  > **Tutorial:** <a href="http://www.codeproject.com/Articles/829349/Introducing-Portable-Generic-Image-Library-for-Csh" target="_blank">Portable Generic Image</a>

 ``` csharp
//convert to grayscale and flip
Bgr<byte>[,] image = ImageIO.LoadColor("sample.jpg"); //IO package
Gray<byte>[,] grayIm = image.ToGray()
                             .Flip(FlipDirection.Horizontal);

//get the modified blue channel 
var modifiedImage = image.AsEnumerable()
	                 .Select(x => x.B / 2)
			 .ToArray2D(image.Size());
 ```

+ <a href="https://www.nuget.org/packages/DotImaging.Primitives2D"> 
    <img src="https://img.shields.io/badge/DotImaging-Primitives2D-red.svg?style=flat-square" alt="DotImaging.Primitives2D"/>  
  </a> 
  Portable 2D drawing primitives (Extensions for Point, Size, Rectangle and additional primitives)

###### IO

+ <a href="https://www.nuget.org/packages/DotImaging.IO"> 
    <img src="https://img.shields.io/badge/DotImaging-IO-red.svg?style=flat-square" alt="DotImaging.IO"/>  
  </a>
  A unified API for IO image access (camera, file, image directory). Portable image loading/saving.

  > **Tutorial:** <a href="http://www.codeproject.com/Articles/828012/Introducing-Portable-Video-IO-Library-for-Csharp" target="_blank">Portable Imaging IO</a>

 ``` csharp
var reader = new FileCapture("sample.mp4");
reader.Open();

Bgr<byte>[,] frame = null;
while(true)
{
       reader.ReadTo(ref frame);
       if (frame == null)
          break;

       frame.Show(scaleForm: true); //UI package
}

reader.Close();
 ``` 
 
+ <a href="https://www.nuget.org/packages/DotImaging.IO.Web"> 
    <img src="https://img.shields.io/badge/DotImaging-IO.Web-red.svg?style=flat-square" alt="DotImaging.IO.Web"/>  
  </a>
  Image or video download/streaming (direct video link or Youtube links).

 ``` csharp
//------get an image from the Web
new Uri("http://vignette3.wikia.nocookie.net/disney/images/5/5d/Lena_headey_.jpg")
     .GetBytes().DecodeAsColorImage().Show(); //(Show - UI package)
 
//------stream a video from Youtube
var pipeName = new Uri("https://www.youtube.com/watch?v=Vpg9yizPP_g").NamedPipeFromYoutubeUri(); //Youtube
var reader = new FileCapture(String.Format(@"\\.\pipe\{0}", pipeName)) //IO package
 
//... (regular stream reading - see IO package sample)
 ``` 

 
###### Interoperability

+ <a href="https://www.nuget.org/packages/DotImaging.BitmapInterop"> 
    <img src="https://img.shields.io/badge/DotImaging-BitmapInterop-red.svg?style=flat-square" alt="DotImaging.BitmapInterop"/>  
  </a>
  Interoperability extensions between .NET array and System.Drawing.Bitmap.

 ``` csharp
var image = new Gray<byte>[240, 320];
var bmp = image.ToBitmap(); //to Bitmap

var imageFromBmp = bmp.ToArray() as Bgr<byte>[,]; //from Bitmap
 ``` 
 
 
###### Extensions

+ <a href="https://www.nuget.org/packages/DotImaging.UI.Image"> 
    <img src="https://img.shields.io/badge/DotImaging-UIImage-red.svg?style=flat-square" alt="DotImaging.UI"/>  
  </a> 
  Image preview dialog and drawing.

 ``` csharp
Bgr<byte>[,] image = new Bgr<byte>[480, 640];
image.Show(); //show image (non-blocking)
image.ShowDialog(); //show image (blocking)

//draw something
image.Draw(new Rectangle(50, 50, 200, 100), Bgr<byte>.Red, -1);
image.Draw(new Circle(50, 50, 25), Bgr<byte>.Blue, 5);
 ```
  
## Getting started
+ Just pick what you need. An appropriate readme file will be shown upon selected NuGet package installation. 
+ Samples

## Final word
If you like the project please **star it** in order to help to spread the word. That way you will make the framework more significant and in the same time you will motivate me to improve it, so the benefit is mutual.


================================================
FILE: Samples/Sample.Basic/Program.cs
================================================
using DotImaging;
using System.Drawing;
using System;
using System.IO;

namespace BasicImageOperations
{
    static class Program
    {
        static void Main()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            //load from the Web
            var image = new Uri("http://vignette3.wikia.nocookie.net/disney/images/5/5d/Lena_headey_.jpg")
                            .GetBytes()
                            .DecodeAsColorImage();

            //show image
            image.Show("New Lena");

            //draw something
            image.DrawRectangle(new Rectangle(50, 50, 200, 100), Bgr<byte>.Red, -1);
            image.DrawText("Hello world!", DotImaging.Font.Big, new Point(10, 100), Bgr<byte>.White);

            //save and load
            image.Save("out.png");
            ImageIO.LoadColor("out.png").ShowDialog("Saved image", autoSize: true);
        }
    }
}


================================================
FILE: Samples/Sample.Basic/Sample.Basic.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <OutputType>Exe</OutputType>
    <Platforms>x64</Platforms>
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\BitmapInterop\Image.BitmapInterop.csproj" />
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
    <ProjectReference Include="..\..\Source\IO.Web\IO.Web.csproj" />
	  <ProjectReference Include="..\..\Source\IO\IO.csproj" />
	  <ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.Capture/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using DotImaging;
using System;
using System.IO;

namespace Capture
{
    class Program
    {
        [STAThread]
        static void Main()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            Console.WriteLine("Press ESC to stop playing");

            //var reader = new CameraCapture(0); //capture from camera
            //(reader as CameraCapture).FrameSize = new Size(640, 480);

            var reader = new FileCapture(Path.Combine(getResourceDir(), "Welcome.mp4")); //capture from video
            //var reader = new ImageDirectoryCapture(Path.Combine(getResourceDir(), "Sequence"), "*.jpg");
            reader.Open();
    
            Bgr<byte>[,] frame = null;
            do
            {
                reader.ReadTo(ref frame);
                if (frame == null)
                    break;

                frame.Show(autoSize: true);
            }
            while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape));

            reader.Dispose();
            ImageUI.CloseAll();
        }

        private static string getResourceDir()
        {
            return Path.Combine(new DirectoryInfo(Environment.CurrentDirectory).FullName, "Resources");
        }
    }
}


================================================
FILE: Samples/Sample.Capture/Sample.Capture.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup>
    
  <ItemGroup>
    <None Update="Resources\Welcome.mp4">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.CaptureAndRecord/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2016
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using DotImaging;
using System;
using System.IO;

namespace CaptureAndRecording
{
    static class Program
    {
        static void Main()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            //var reader = new CameraCapture(0); //capture from camera
            var reader = new FileCapture(Path.Combine(getResourceDir(), "Welcome.mp4"));
           reader.Open();

           var writer = new VideoWriter(@"output.avi", reader.FrameSize, /*reader.FrameRate does not work Cameras*/ 30); //TODO: bug: FPS does not work for cameras
           writer.Open();

            Bgr<byte>[,] frame = null;
            do
            {
                reader.ReadTo(ref frame);
                if (frame == null)
                    break;

                using (var uFrame = frame.Lock())
                { writer.Write(uFrame); }

                frame.Show(autoSize: true);
            }
            while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape));

            reader.Dispose();
            writer.Dispose();

            ImageUI.CloseAll();
        }

        private static string getResourceDir()
        {
            return Path.Combine(new DirectoryInfo(Environment.CurrentDirectory).FullName, "Resources");
        }
    }
}


================================================
FILE: Samples/Sample.CaptureAndRecord/Sample.CaptureAndRecord.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup>
    
  <ItemGroup>
    <None Update="Resources\Welcome.mp4">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.ImageExtractor/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2016
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using DotImaging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace ImageExtractor
{
    class Program
    {
        static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            //emulate input args
            string fileMask = Path.Combine(getResourceDir(), "Welcome.mp4");

            if (args.Length == 1)
                fileMask = args[0];

            var fileNames = enumerateFiles(fileMask);
            foreach (var fileName in fileNames)
            {
                extractVideo(fileName);
            }
        }

        private static void extractVideo(string fileName)
        {
            //get output dir (same as file name and in the same folder as video)
            var fileInfo = new FileInfo(fileName);
            var fileNameNoExt = fileInfo.Name.Replace(fileInfo.Extension, String.Empty);
            string outputDir = Path.Combine(fileInfo.DirectoryName, fileNameNoExt);

            //open video
            var reader = new FileCapture(fileName);
            reader.Open();

            reader.SaveFrames(outputDir, "{0}.jpg", p => Console.Write($"\rExtracting: {(int)(p * 100)} %"));
            ImageUI.CloseAll();
        }

        private static IEnumerable<string> enumerateFiles(string fileMask)
        {
            var pathDelimiter = Path.DirectorySeparatorChar;

            fileMask = normalizePathDelimiters(fileMask, pathDelimiter.ToString());
            string fileMaskWithoutPath = fileMask.Split(pathDelimiter).Last();
            string path = fileMask.Replace(fileMaskWithoutPath, String.Empty);

            var fileNames = Directory.EnumerateFiles(path, fileMaskWithoutPath);
            return fileNames;
        }

        private static string getResourceDir()
        {
            return Path.Combine(new DirectoryInfo(Environment.CurrentDirectory).FullName, "Resources");
        }

        private static string normalizePathDelimiters(string path, string normalizedDelimiter) //TODO: replace with extension when available
        {
            return path.Replace("//", normalizedDelimiter)
                       .Replace(@"\", normalizedDelimiter)
                       .Replace(@"\\", normalizedDelimiter)
                       .Replace(@"/", normalizedDelimiter);
        }
    }
}


================================================
FILE: Samples/Sample.ImageExtractor/Sample.ImageExtractor.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup>
    
  <ItemGroup>
    <None Update="Resources\Welcome.mp4">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.Interop/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2016
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using DotImaging;
using System;
using System.IO;

namespace GenericImageInteropDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            var img = new Bgr<byte>[480, 640];

            //***********************************************************************************************************************************************************************
            Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("********* TColor[,] <=> Image<> conversions (built-in) ****************"); Console.ResetColor();
            //to Image<>
            Image<Bgr<byte>> lockedImg = img.Lock();
            //from Image<>
            var arr = lockedImg.Clone();

            //***********************************************************************************************************************************************************************
            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("********* Image<,> <=> OpenCV conversions (built-in) ****************"); Console.ResetColor();
            //to IplImage
            IplImage iplImage;
            using (var uImg = img.Lock())
            {
                iplImage = uImg.AsCvIplImage(); //data is shared
            }
            //from IplImage
            var imgFromIpl = iplImage.AsImage(); 

            //***********************************************************************************************************************************************************************
            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("*********** Image<,> <=> Bitmap conversions (BitmapInterop) ****************"); Console.ResetColor();
            //to Bitmap
            var bmp = img.ToBitmap();
            //from Bitmap
            var imgFromBmp = bmp.ToImage<Bgr<byte>>();
        }
    }
}


================================================
FILE: Samples/Sample.Interop/Sample.Interop.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\BitmapInterop\Image.BitmapInterop.csproj" />
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup> 
 
</Project>


================================================
FILE: Samples/Sample.MultipleCameraCapture/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2016
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using DotImaging;
using System.Collections.Generic;
using System.IO;

namespace MultipleCameraCapture
{
    static class Program
    {
        static void Main()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            Console.WriteLine("Press ESC to stop playing");

            List<CameraCapture> captures = new List<CameraCapture>();

            var cameraCount = CameraCapture.CameraCount;
            if (cameraCount == 0)
            {
                Console.WriteLine("No camera device is present.");
                return;
            }

            //initialize
            for (int camIdx = 0; camIdx < cameraCount; camIdx++)
            {
                var cap = new CameraCapture(camIdx);
                cap.Open();

                captures.Add(cap);
            }

            //grab frames
            Bgr<byte>[][,] frames = new Bgr<byte>[cameraCount][,];
            do
            {
                for (int camIdx = 0; camIdx < cameraCount; camIdx++)
                {
                    captures[camIdx].ReadTo(ref frames[camIdx]);
                    if (frames[camIdx] == null)
                        break;

                    frames[camIdx].Show(String.Format("Camera {0}", camIdx), autoSize: true);
                }
            }
            while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape));

            //dispose
            captures.ForEach(x => x.Dispose());
            ImageUI.CloseAll();
        }
    }
}


================================================
FILE: Samples/Sample.MultipleCameraCapture/Sample.MultipleCameraCapture.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.UI/Program.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2016
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using DotImaging;
using DotImaging.Linq;
using System.Linq;
using System;
using System.Threading;
using System.IO;

namespace UIDemo
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced

            //select color
            Bgr<byte>[,] image = new Bgr<byte>[480, 640];
            Hsv<byte> color = UI.PickColor(Bgr<byte>.Red).ToHsv();

            //select mask
            Gray<byte>[,] mask = image.GetMask();
            if (mask.AsEnumerable().Sum(x => x.Intensity) == 0) //if the mask is empty
                mask.SetValue<Gray<byte>>(Byte.MaxValue);

            //increase saturation incrementally
            for (int s = 0; s <= Byte.MaxValue; s++)
            {
                color.S = (byte)s;
                image.SetValue<Bgr<byte>>(color.ToBgr(), mask);

                image.Show(scaleForm: true);
                ((double)s / Byte.MaxValue).Progress(message: "Changing saturation");

                Thread.Sleep(50);
            }

            //save last image
            string fileName = UI.SaveImage();
            if (fileName != null) image.Save(fileName);

            //close all
            UI.CloseAll();
        }
    }
}


================================================
FILE: Samples/Sample.UI/Sample.UI.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>net47</TargetFrameworks>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
    <ProjectReference Include="..\..\Source\LINQ\Linq.csproj" />
    <ProjectReference Include="..\..\Source\Primitives2D\Primitives2D.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI\UI.csproj" />
  </ItemGroup> 
</Project>


================================================
FILE: Samples/Sample.VideoStreaming/Program.cs
================================================
using DotImaging;
using System;
using System.Diagnostics;
using System.IO;

namespace YoutubeStreaming
{
    class Program
    {
        public static void Main()
        {
            Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
            Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";runtimes/win10-x64/"); //only needed if projects are directly referenced


            var sourceName = String.Empty;

            //video over pipe (direct link and Youtube) (do not support seek)
            //var pipeName = new Uri("http://trailers.divx.com/divx_prod/divx_plus_hd_showcase/BigBuckBunny_DivX_HD720p_ASP.divx").NamedPipeFromVideoUri(); //web-video
            var pipeName = new Uri("https://www.youtube.com/watch?v=Vpg9yizPP_g").NamedPipeFromYoutubeUri(); //Youtube
            sourceName = String.Format(@"\\.\pipe\{0}", pipeName);

            //video http link (Supports seek)
            //sourceName = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4";

            //---------------------------------------------
            ImageStreamReader reader = new FileCapture(sourceName);
            reader.Open();

            //seek if you can
            if(reader.CanSeek)
                reader.Seek((int)(reader.Length * 0.25), System.IO.SeekOrigin.Begin);

            //read video frames
            Bgr<byte>[,] frame = null;
            while(true)
            {
                reader.ReadTo(ref frame);
                if (frame == null)
                    break;

                frame.Show(autoSize: false);
                Console.Write($"\r Received: {reader.Position * 100 / reader.Length}%");
            }
            Console.WriteLine("The end.");

            //---------------------------------------------------------------------------
            ImageUI.CloseAll();
            Console.WriteLine("Downloading video...");

            string fileExtension;
            var downloadPipeName = new Uri("https://www.youtube.com/watch?v=Vpg9yizPP_g").NamedPipeFromYoutubeUri(out fileExtension); //Youtube

            downloadPipeName.SaveNamedPipeStream("out" + fileExtension);
            Console.WriteLine("Video saved.");
            Process.Start("out" + fileExtension); //open local file
        }
    }
}


================================================
FILE: Samples/Sample.VideoStreaming/Sample.VideoStreaming.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>
    <Platforms>x64</Platforms>
  </PropertyGroup>

  <PropertyGroup>
    <RootNamespace>DotImaging</RootNamespace>
    <OutputPath>bin\</OutputPath>
    <ApplicationIcon />
    <OutputType>Exe</OutputType>
    <StartupObject />
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\..\Source\Image\Image.csproj" />
    <ProjectReference Include="..\..\Source\IO.Web\IO.Web.csproj" />
	<ProjectReference Include="..\..\Source\IO\IO.csproj" />
	<ProjectReference Include="..\..\Source\UI.Image\UI.Image.csproj" />
  </ItemGroup> 
</Project>


================================================
FILE: Source/BitmapInterop/.nuSpec/readmeImage.Bitmap.txt
================================================
Provides extensions for interoperability with System.Drawing.Bitmap, Point, PointF, Color and drawing extensions.

1) Array <-> Bitmap conversion:

	var image = new Gray<byte>[240, 320];
	var bmp = image.ToBitmap();

	var imageFromBmp = bmp.ToArray() as Bgr<byte>[,]; 

2) System.Drawing.Color <-> DotImaging color conversion:

	var aquaColor = System.Drawing.Color.Aqua.ToBgr();


3) Save bitmap with quality selection
	
	var bmp = Bitmap.FromFile("sample.bmp");
	bmp.Save("compressed.jpg", 85);


Discover more extensions as you type :)

================================================
FILE: Source/BitmapInterop/BmpExtensions/BitmapConversion.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

namespace DotImaging
{
    /// <summary>
    /// Provides conversion extension methods between generic image and <see cref="System.Drawing.Bitmap"/>.
    /// </summary>
    public static class BitmapConversionExtensions
    {
        #region Conversion from Bitmap

        static Dictionary<Type, PixelFormat> mapingTable = new Dictionary<Type, PixelFormat>
        {
            { typeof(Gray<byte>),  PixelFormat.Format8bppIndexed },
            { typeof(Gray<short>), PixelFormat.Format16bppGrayScale },
            { typeof(Bgr<byte>),   PixelFormat.Format24bppRgb },
            { typeof(Bgra<byte>),  PixelFormat.Format32bppArgb },
            { typeof(Bgr<short>),  PixelFormat.Format48bppRgb },
            { typeof(Bgra<short>), PixelFormat.Format64bppArgb },
        };

        /// <summary>
        /// Converts a bitmap to an image (copies data). 
        /// </summary>
        /// <param name="bmp">Input bitmap.</param>
        /// <typeparam name="TColor">Target color type.</typeparam>
        /// <returns>2D array.</returns>
        public static TColor[,] ToImage<TColor>(this Bitmap bmp)
            where TColor: unmanaged, IColor
        {
            if (mapingTable.TryGetValue(typeof(TColor), out var targetPixelFmt) == false)
                throw new NotSupportedException("Target mapping not found.");

            TColor[,] arr = null;
            using (Bitmap targetBmp = bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), targetPixelFmt))
            {
                var bmpData = targetBmp.LockBits(ImageLockMode.ReadOnly);
                arr = new TColor[targetBmp.Height, targetBmp.Width];

                using (var img = arr.Lock())
                {
                    Copy.UnsafeCopy2D(bmpData.Scan0, img.ImageData, bmpData.Stride, img.Stride, bmpData.Height);
                }

                targetBmp.UnlockBits(bmpData);
            }

            return arr;
        }

        #endregion

        #region Conversion To Bitmap

        private static Bitmap toBitmap(IImage img, PixelFormat pixelFormat)
        {
            var bmp = new Bitmap(img.Width, img.Height, pixelFormat);
            var bmpData = bmp.LockBits(ImageLockMode.WriteOnly);
            Copy.UnsafeCopy2D(img.ImageData, bmpData.Scan0, img.Stride, bmpData.Stride, bmpData.Height);
            bmp.UnlockBits(bmpData);

            if (pixelFormat == PixelFormat.Format8bppIndexed)
                bmp.SetGrayscalePalette();

            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Gray<byte>> img)
        {
            return toBitmap(img, PixelFormat.Format8bppIndexed);
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Gray<short>> img)
        {
            return toBitmap(img, PixelFormat.Format16bppGrayScale);
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Bgr<byte>> img)
        {
            return toBitmap(img, PixelFormat.Format24bppRgb);
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Bgra<byte>> img)
        {
            return toBitmap(img, PixelFormat.Format32bppArgb);
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Bgr<short>> img)
        {
            return toBitmap(img, PixelFormat.Format48bppRgb);
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Image<Bgra<short>> img)
        {
            return toBitmap(img, PixelFormat.Format64bppArgb);
        }


        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Gray<byte>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format8bppIndexed); 
            }
            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Gray<short>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format16bppGrayScale);
            }
            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Bgr<byte>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format24bppRgb);
            }
            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Bgra<byte>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format32bppArgb);
            }
            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Bgr<short>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format48bppRgb);
            }
            return bmp;
        }

        /// <summary>
        /// Converts an image to an bitmap.
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap ToBitmap(this Bgra<short>[,] img)
        {
            Bitmap bmp = null;
            using (var uImg = img.Lock())
            {
                bmp = toBitmap(uImg, PixelFormat.Format64bppArgb);
            }
            return bmp;
        }

        #endregion

        #region Cast to Bitmap

        private static Bitmap asBitmap(IImage img, PixelFormat pixelFormat)
        {
            var bmp = new Bitmap(img.Width, img.Height, img.Stride, pixelFormat, img.ImageData);

            if (pixelFormat == PixelFormat.Format8bppIndexed)
                bmp.SetGrayscalePalette();

            return bmp;
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Gray<byte>> img)
        {
            return asBitmap(img, PixelFormat.Format8bppIndexed);
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Gray<short>> img)
        {
            return asBitmap(img, PixelFormat.Format16bppGrayScale);
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Bgr<byte>> img)
        {
            return asBitmap(img, PixelFormat.Format24bppRgb);
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Bgra<byte>> img)
        {
            return asBitmap(img, PixelFormat.Format32bppArgb);
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Bgr<short>> img)
        {
            return asBitmap(img, PixelFormat.Format48bppRgb);
        }

        /// <summary>
        /// Casts an image to an bitmap.
        /// <para>Notice that GDI+ does not support bitmaps which stride is not 4.</para>
        /// </summary>
        /// <param name="img">Input image.</param>
        /// <returns>Bitmap</returns>
        public static Bitmap AsBitmap(this Image<Bgra<short>> img)
        {
            return asBitmap(img, PixelFormat.Format64bppArgb);
        }

        #endregion

        #region Misc
 
        /// <summary>
        /// Replaces color palette entries with grayscale intensities (256 entries).
        /// </summary>
        /// <param name="image">The 8-bpp grayscale image.</param>
        public static void SetGrayscalePalette(this Bitmap image)
        {
            if (image.PixelFormat != PixelFormat.Format8bppIndexed)
                throw new ArgumentException("The provided image must have 8bpp pixel format.");

            var palette = image.Palette;
            for (int i = 0; i < (Byte.MaxValue + 1); i++)
            {
                palette.Entries[i] = Color.FromArgb(i, i, i);
            }

            image.Palette = palette;
        }

        /// <summary>
        /// Lock a <see cref="System.Drawing.Bitmap"/> into system memory.
        /// </summary>
        /// <param name="bmp">Bitmap to lock.</param>
        /// <param name="imageLockMode">Specifies the access level.</param>
        /// <returns>Bitmap data.</returns>
        public static BitmapData LockBits(this Bitmap bmp, ImageLockMode imageLockMode = ImageLockMode.ReadWrite)
        {
            return bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), imageLockMode, bmp.PixelFormat);
        }

        #endregion
    }
}


================================================
FILE: Source/BitmapInterop/BmpExtensions/BmpIO.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;

namespace DotImaging
{
    /// <summary>
    /// Bitmap file save extensions.
    /// </summary>
    public static class BmpIO
    {
        static Dictionary<string, ImageCodecInfo> codecs = null;

        static BmpIO()
        {
            codecs = new Dictionary<string, ImageCodecInfo>();

            codecs.Add(".jpg", getEncoder(ImageFormat.Jpeg));
            codecs.Add(".jpeg", getEncoder(ImageFormat.Jpeg));
            codecs.Add(".png", getEncoder(ImageFormat.Png));
        }

        private static ImageCodecInfo getEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }


        /// <summary>
        /// Saves the specified image.
        /// <para>
        /// Quality parameter is only supported for JPEG, PNG file types. 
        /// For other file types this value is omitted.
        /// </para>
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="targetStream">Target stream.</param>
        /// <param name="imageFormat">Image format.</param>
        /// <param name="quality">Quality parameter [0..100] where 0 means maximum compression.</param>
        public static void Save(this System.Drawing.Image image, Stream targetStream, ImageFormat imageFormat, int quality = 90)
        {
            var encoder = getEncoder(imageFormat);

            if (encoder != null)
            {
                System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
                EncoderParameters myEncoderParameters = new EncoderParameters(1);
                myEncoderParameters.Param[0] = new EncoderParameter(myEncoder, quality);

                image.Save(targetStream, encoder, myEncoderParameters);
            }
            else
            {
                image.Save(targetStream, imageFormat);
            }
        }


        /// <summary>
        /// Saves the specified image.
        /// <para>
        /// Quality parameter is only supported for JPEG, PNG file types. 
        /// For other file types this value is omitted.
        /// </para>
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="filename">File name.</param>
        /// <param name="quality">Quality parameter [0..100] where 0 means maximum compression.</param>
        public static void Save(this System.Drawing.Image image, string filename, int quality = 90)
        {
            codecs.TryGetValue(new FileInfo(filename).Extension, out ImageCodecInfo codec);
            if (codec == null)
            {
                image.Save(filename);
                return;
            }

            System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
            EncoderParameters myEncoderParameters = new EncoderParameters(1);
            myEncoderParameters.Param[0] = new EncoderParameter(myEncoder, quality);

            image.Save(filename, codec, myEncoderParameters);
        }
    }
}


================================================
FILE: Source/BitmapInterop/BmpExtensions/ColorConversion.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Drawing;

namespace DotImaging
{
    /// <summary>
    /// Contains color format conversion extensions.
    /// </summary>
    public static class ColorConversion
    {
        /// <summary>
        /// Gets System.Drawing.Color from Bgr8 color.
        /// </summary>
        /// <param name="color">Color.</param>
        /// <param name="opacity">Opacity. If color has 4 channels opacity is discarded.</param>
        /// <returns>System.Drawing.Color</returns>
        public static System.Drawing.Color ToColor(this Gray<byte> color, byte opacity = Byte.MaxValue)
        {
            return Color.FromArgb(opacity, color.Intensity, color.Intensity, color.Intensity);
        }

        /// <summary>
        /// Gets System.Drawing.Color from Bgr8 color.
        /// </summary>
        /// <param name="color">Color.</param>
        /// <param name="opacity">Opacity. If color has 4 channels opacity is discarded.</param>
        /// <returns>System.Drawing.Color</returns>
        public static System.Drawing.Color ToColor(this Bgr<byte> color, byte opacity = Byte.MaxValue)
        {
            return Color.FromArgb(opacity, color.R, color.G, color.B);
        }

        /// <summary>
        /// Gets System.Drawing.Color from Bgra8 color.
        /// </summary>
        /// <param name="color">Color.</param>
        /// <returns>System.Drawing.Color</returns>
        public static System.Drawing.Color ToColor(this Bgra<byte> color)
        {
            return Color.FromArgb(color.A, color.R, color.G, color.B);
        }

        /// <summary>
        /// Converts (casts) the color into 32-bit BGR color.
        /// </summary>
        /// <param name="color">Color.</param>
        /// <returns>Bgr representation.</returns>
        public static Bgr<byte> ToBgr(this System.Drawing.Color color)
        {
            return new Bgr<byte> { B = color.B, G = color.G, R = color.R };
        }
    }
}


================================================
FILE: Source/BitmapInterop/Image.BitmapInterop.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <AssemblyName>DotImaging.BitmapInterop</AssemblyName>
    <RootNamespace>DotImaging</RootNamespace>
    <Platforms>AnyCPU</Platforms>
  </PropertyGroup>
    
  <ItemGroup>
    <PackageReference Include="System.Drawing.Common" Version="4.5.1" />
    <ProjectReference Include="..\Image\Image.csproj" />
  </ItemGroup> 

  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <DocumentationFile>bin\DotImaging.BitmapInterop.xml</DocumentationFile>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
  </PropertyGroup>


  <!-- NuGet -->
  <PropertyGroup>
    <Version>5.3.0</Version>

    <PackageId>DotImaging.BitmapInterop</PackageId>
    <Description>Extensions for interoperability with System.Drawing.Bitmap.</Description>
    <PackageTags>imaging interoperability extensions, GDI</PackageTags>

    <Authors>Darko Jurić</Authors>
    <Copyright>Darko Jurić</Copyright>
    <PackageLicenseUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Licence.txt</PackageLicenseUrl>
    <PackageIconUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Logo/logo-small.png</PackageIconUrl>
    <PackageProjectUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</PackageProjectUrl>
    <RepositoryUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</RepositoryUrl>

    <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
    <PackageOutputPath>../../Deploy/NuGet/bin/</PackageOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <Content Include=".nuSpec\readmeImage.Bitmap.txt">
      <PackagePath>Readme.txt</PackagePath>
    </Content>
  </ItemGroup>
</Project>


================================================
FILE: Source/IO/.nuSpec/readmeIO.txt
================================================
Unified stream-like platform-abstract API for IO video access: web-camera support, various video-format reading / writing, image-directory reader.
Image loading/saving (file or in-memory).

1) image loading / saving:

   Bgr<byte>[,] image = ImageIO.LoadColor("sample.jpg"); //load Bgr color image
   Gray<float>[,] hdrImage = (ImageIO.LoadUnchanged("hdrImage.png") as Image<Gray<float>>).Clone(); //load HDR grayscale (or any other) image
   image.Save("image.png");


2) image in-memory encoding / decoding

   Bgr<byte>[,] bgrIm = ImageIO.LoadColor("sample.jpg");
   byte[] encodedBgr = bgrIm.EncodeAsJpeg(); //or png, bmp
   Bgr<byte>[,] decodedBgr = encodedBgr.DecodeAsColorImage();


3) media (camera, video, image-directory) capture:

   ImageStreamReader reader = new CameraCapture(); //use specific class for device-specific properties (e.g. exposure, image name, ...)
   reader.Open();

   //read single frame
   var frame = reader.Read().ToBgr();
   reader.Close();
   

4) video writer:

   ImageStreamWriter videoWriter = new VideoWriter("out.avi", new Size(1280, 1024));

   var image = new Bgr<byte>[1024, 1280];
   videoWriter.Write(image.Lock()); //write a single frame

   videoWriter.Close();

5) frame extraction:

	var reader = new FileCapture(fileName);
    reader.Open();

    reader.SaveFrames(outputDir, "{0}.jpg", (percentage) =>
    {
        ((double)percentage).Progress(message: "Extracting video...");
    });

	reader.Close();


Discover more types as you type :)




================================================
FILE: Source/IO/Base/Abstract/ImageStream.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.IO;

namespace DotImaging
{
    /// <summary>
    /// Provides the base class for the image stream.
    /// </summary>
    /// <typeparam name="TImage">Image type.</typeparam>
    public abstract class ImageStream<TImage>: IDisposable
    {
        /// <summary>
        /// Initializes a new instance of <see cref="ImageStream{TImage}"/>.
        /// </summary>
        protected ImageStream()
        {
            this.CanSeek = false;
            this.IsLiveStream = false;
        }

       /// <summary>
       /// When overridden in a derived class, gets the length in number of frames.
       /// </summary>
        public abstract long Length { get; }

        /// <summary>
        /// When overridden in a derived class, gets the next frame index.
        /// </summary>
        public virtual long Position { get; protected set; }

        /// <summary>
        /// Gets whether the stream is live stream meaning that its length is not constant.
        /// Those streams are usually not seek-able. See also: <see cref="CanSeek"/>.
        /// </summary>
        public virtual bool IsLiveStream { get; protected set; }

        /// <summary>
        /// Gets a value indicating whether the current stream supports seeking.
        /// </summary>
        public virtual bool CanSeek { get; protected set; }

        /// <summary>
        /// When overridden in a derived class, sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A frame index offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        /// <exception cref="NotSupportedException">Seek operation is not supported by the current stream.</exception>
        public virtual long Seek(long offset, System.IO.SeekOrigin origin = SeekOrigin.Current)
        {
            if (!this.CanSeek)
                throw new NotSupportedException("Seek operation is not supported by the current stream.");

            long newPosition = 0;
            switch (origin)
            {
                case SeekOrigin.Begin:
                    newPosition = offset;
                    break;
                case SeekOrigin.Current:
                    newPosition = this.Position + offset;
                    break;
                case SeekOrigin.End:
                    newPosition = this.Length + offset;
                    break;
            }

            var currentFrame = System.Math.Min(this.Length - 1, System.Math.Max(0, newPosition));
            return currentFrame;
        }

        /// <summary>
        /// Closes the stream and releases all resources.
        /// <para>Use Dispose function rather than Close function.</para>
        /// </summary>
        public virtual void Dispose()
        {
            this.Close();
        }

        /// <summary>
        /// When overridden in a derived class, opens the current stream. 
        /// </summary>
        public abstract void Open();

        /// <summary>
        /// When overridden in a derived class, closes the current stream and releases any resources associated with the current stream.
        /// This function is internally called by <see cref="Dispose"/>.
        /// </summary>
        public abstract void Close();
    }
}


================================================
FILE: Source/IO/Base/Abstract/ImageStreamReader.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;

namespace DotImaging
{
    /// <summary>
    /// Image stream reader abstract class. 
    /// See generic class also.
    /// </summary>
    public abstract class ImageStreamReader: ImageStreamReader<IImage>
    { }

    /// <summary>
    /// Image stream writer abstract class. 
    /// It is the base class for classes providing image stream reading.
    /// </summary>
    /// <typeparam name="TImage">Image type.</typeparam>
    public abstract class ImageStreamReader<TImage> : ImageStream<TImage>, IEnumerable<TImage>
    {
        /// <summary>
        /// Initializes a new instance of the image reader class.
        /// </summary>
        protected ImageStreamReader()
        {
            this.ReadTimeout = 100;
        }

        /// <summary>
        /// Gets or sets a value, in milliseconds, that determines how long the stream will attempt to read before timing out.
        /// </summary>
        public int ReadTimeout { get; set; }

        /// <summary>
        /// Creates and starts the task responsible for frame reading.
        /// If this function is called <see cref="ReadTimeout"/> must be handled by a user itself.
        /// <remarks>
        /// By using this function reading from some streams can be accelerated.
        /// </remarks>
        /// </summary>
        /// <returns>A image reading task.</returns>
        public Task<TImage> ReadAsync()
        {
            var readTask = new Task<TImage>(() =>
            {
                TImage result;
                ReadInternal(out result);
                return result;
            });

            readTask.Start();
            return readTask;
        }

        /// <summary>
        /// Reads an image from the current stream 
        /// and advances the position within the stream by 1 element.
        /// </summary>
        /// <param name="isExpired">If a null is returned this can be due to <see cref="ReadTimeout"/> has been reached.</param>
        /// <returns>Read image.</returns>
        public TImage Read(out bool isExpired)
        {
            var readTask = ReadAsync();
            readTask.Wait(this.ReadTimeout);

            isExpired = !readTask.IsCompleted;
            return readTask.Result;
        }

        /// <summary>
        /// Reads an image from the current stream 
        /// and advances the position within the stream by usually 1 element.
        /// </summary>
        /// <returns>Read image.</returns>
        public TImage Read() 
        {
            bool isExpired;
            return Read(out isExpired);
        }

        /// <summary>
        /// When overridden in a derived class returns an image and a status.
        /// Position is advanced.
        /// </summary>
        /// <param name="image">Read image.</param>
        /// <returns></returns>
        protected abstract bool ReadInternal(out TImage image);

        #region IEnumerable

        /// <summary>
        /// Gets the enumerator for the stream.
        /// <para>If the stream does not support seek, an exception will be thrown during iteration.</para>
        /// </summary>
        /// <returns>Enumerator for the stream.</returns>
        public IEnumerator<TImage> GetEnumerator()
        {
            return new ImageStreamReaderEnumerator<TImage>(this);
        }

        /// <summary>
        /// Gets the enumerator for the stream.
        /// <para>If the stream does not support seek, an exception will be thrown during iteration.</para>
        /// </summary>
        /// <returns>Enumerator for the stream.</returns>
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return (IEnumerator)GetEnumerator();
        }

        #endregion
    }

    /// <summary>
    /// Enumerator for the image stream.
    /// <para>Stream must support seek operation.</para>
    /// </summary>
    /// <typeparam name="TImage">Image type.</typeparam>
    public class ImageStreamReaderEnumerator<TImage> : IEnumerator<TImage>
    {
        ImageStreamReader<TImage> streamableSource;
        long length = -1;
        int position;

        /// <summary>
        /// Creates new image stream iterator.
        /// </summary>
        /// <param name="streamableSource">Image stream.</param>
        public ImageStreamReaderEnumerator(ImageStreamReader<TImage> streamableSource)
        {
            this.streamableSource = streamableSource;
            this.length = streamableSource.Length;

            Reset();
        }

        /// <summary>
        /// Moves the position of the iterator by 1.
        /// </summary>
        /// <returns>True if the position increment is valid, false otherwise.</returns>
        public bool MoveNext()
        {
            position++;
            return position < length;
        }

        /// <summary>
        /// Resets the enumerator,
        /// </summary>
        public void Reset()
        {
            streamableSource.Seek(0, SeekOrigin.Begin);
            position = -1;
        }

        /// <summary>
        /// Gets the current image within the stream.
        /// </summary>
        public TImage Current
        {
            get 
            {
                var realPos = streamableSource.Position;

                if (position != realPos)
                    streamableSource.Seek(position, SeekOrigin.Begin);

                var currentImage = streamableSource.Read();
                return currentImage;
            }
        }

        /// <summary>
        /// Gets the current image within the stream.
        /// </summary>
        object System.Collections.IEnumerator.Current
        {
            get { return this.Current; }
        }

        bool isDisposed = false;
        /// <summary>
        /// Disposes the iterator and resets the position within the stream.
        /// </summary>
        public void Dispose()
        {
            if (!isDisposed)
            {
                Reset();
                isDisposed = true;
            }
        }
    }

    /// <summary>
    /// Provides extensions for image stream.
    /// </summary>
    public static class ImageStreamReaderExtensions
    {
        /// <summary>
        /// Calls read function defined by the stream and converts an returned image if necessary.
        /// <para>If the image can not be read (null), null is returned.</para>
        /// </summary>
        /// <param name="imageStream">Image stream.</param>
        /// <returns>Converted image or null if the image can not be read.</returns>
        public static Image<TColor> ReadAs<TColor>(this ImageStreamReader<IImage> imageStream)
            where TColor: unmanaged
        {
            var image = imageStream.Read();
            if (image == null)
                return null;

            return image as Image<TColor>;
        }

        /// <summary>
        /// Reads an element form the input stream and fills the specified buffer.
        /// <para>If the read element does not match the specified type a null value will be written.</para>
        /// </summary>
        /// <typeparam name="TColor">Color type.</typeparam>
        /// <param name="imageStream">Image source stream.</param>
        /// <param name="buffer">
        /// Buffer to write to.
        /// <para>The specified buffer can be null, as it is managed by the function itself.</para>
        /// </param>
        public static void ReadTo<TColor>(this ImageStreamReader<IImage> imageStream, ref TColor[,] buffer)
            where TColor: unmanaged
        { 
            imageStream.ReadAs<TColor>().CopyToOrCreate(ref buffer);
        }
    }
}


================================================
FILE: Source/IO/Base/Abstract/ImageStreamWriter.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System.Threading.Tasks;
using System;

namespace DotImaging
{
    /// <summary>
    /// Image stream writer abstract class. 
    /// See generic class also.
    /// </summary>
    public abstract class ImageStreamWriter : ImageStreamWriter<IImage>
    { }

    /// <summary>
    /// Image stream writer abstract class. 
    /// It is the base class for classes providing image stream reading.
    /// </summary>
    /// <typeparam name="TImage">Image type.</typeparam>
    public abstract class ImageStreamWriter<TImage> : ImageStream<TImage>
    {
        /// <summary>
        /// Initializes a new instance of the image stream writer class.
        /// </summary>
        protected ImageStreamWriter()
        {
            this.WriteTimeout = 500;
        }

        /// <summary>
        /// Gets or sets a value, in milliseconds, that determines how long the writer will attempt to write before timing out.
        /// </summary>
        public int WriteTimeout { get; set; }

        /// <summary>
        /// Creates and starts the task responsible for frame writing.
        /// If this function is called <see cref="WriteTimeout"/> must be handled by a user itself.
        /// <remarks>
        /// By using this function writing to some streams can be accelerated.
        /// </remarks>
        /// </summary>
        /// <returns>An image writing task.</returns>
        public Task<bool> WriteAsync(TImage image)
        {
            var writeTask = new Task<bool>(() =>
            {
                bool success = WriteInternal(image);
                return success;
            });

            writeTask.Start();
            return writeTask;
        }

        /// <summary>
        /// Writes an image from the current stream 
        /// and advances the position within the stream by 1 element.
        /// </summary>
        /// <returns>
        /// True if the operation is successfully completed, 
        /// false if the writer failed to write or the <see cref="WriteTimeout"/> has been reached.
        /// </returns>
        public bool Write(TImage image)
        {
            var writeTask = WriteAsync(image);
            writeTask.Wait(this.WriteTimeout);

            return writeTask.IsCompleted && writeTask.Result;
        }

        /// <summary>
        /// When overridden in a derived class returns an image and a status.
        /// Position is advanced.
        /// </summary>
        /// <param name="image">Image to write.</param>
        /// <returns>True if successful, false otherwise.</returns>
        protected abstract bool WriteInternal(TImage image);
    }

    /// <summary>
    /// Provides extensions for an image stream writer.
    /// </summary>
    public static class ImageStreamWriterExtensions
    {
        /// <summary>
        /// Writes a single image into the specified stream.
        /// </summary>
        /// <typeparam name="TColor">Color type.</typeparam>
        /// <param name="writer">image stream writer.</param>
        /// <param name="image">Image to write.</param>
        /// <returns>True if the writing operation is successful, false otherwise.</returns>
        public static bool Write<TColor>(this ImageStreamWriter<Image<TColor>> writer, TColor[,] image)
            where TColor: unmanaged, IColor
        {
            bool result = false;
            using (var uImg = image.Lock())
            {
                result = writer.Write(uImg);
            }

            return result;
        }
    }
}


================================================
FILE: Source/IO/Base/CvInvoke.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System.Drawing;
using System;
using System.Runtime.InteropServices;
using System.Security;

namespace DotImaging
{
    /// <summary>
    /// OpenCV video codec name.
    /// </summary>
    public class VideoCodec
    {
        /// <summary>
        /// MPEG1 codec name: "PIM1".
        /// </summary>
        public static readonly VideoCodec MPEG1 = VideoCodec.FromName('P', 'I', 'M', '1');
        /// <summary>
        /// Motion JPEG codec name: "MJPG".
        /// </summary>
        public static readonly VideoCodec MotionJpeg = VideoCodec.FromName('M', 'J', 'P', 'G');
        /// <summary>
        /// Intel YUV codec name: "IYUV".
        /// </summary>
        public static readonly VideoCodec IntelYUV = VideoCodec.FromName('I', 'Y', 'U', 'V');
        /// <summary>
        /// User selection - on Windows dialog will be opened. Value: -1.
        /// </summary>
        public static readonly VideoCodec UserSelection = new VideoCodec(-1);

        private const int CODEC_NAME_LENGTH = 4;
        int codec;

        /// <summary>
        /// Creates new video codec from an id.
        /// </summary>
        /// <param name="codec">Codec id.</param>
        private VideoCodec(int codec)
        {
            this.codec = codec;
        }

        /// <summary>
        /// Creates new video codec id from 4-character code. For example, FromName('P','I','M','1') is MPEG-1 codec, FromName('M','J','P','G') is motion-jpeg codec etc.
        /// </summary>
        /// <param name="c1">First char.</param>
        /// <param name="c2">Second char.</param>
        /// <param name="c3">Third char.</param>
        /// <param name="c4">Fourth char.</param>
        /// <returns>Video codec.</returns>
        public static VideoCodec FromName(char c1, char c2, char c3, char c4)
        {
            int codec = (c1 & 255) + ((c2 & 255) << 8) + ((c3 & 255) << 16) + ((c4 & 255) << 24);
            return new VideoCodec(codec);
        }

        /// <summary>
        /// Creates new video codec id from 4-character string.
        /// </summary>
        /// <param name="codecName">4-character string codec name.</param>
        /// <returns>Video codec.</returns>
        public static VideoCodec FromName(string codecName)
        {
            if (codecName.Length != CODEC_NAME_LENGTH)
                throw new Exception("Codec name is 4-characters long!");

            return VideoCodec.FromName(codecName[0], codecName[1], codecName[2], codecName[3]);
        }

        /// <summary>
        /// Casts video codec to an 32-bit integer.
        /// </summary>
        /// <param name="videoCodec">Video codec.</param>
        /// <returns>32-bit integer representation of the video codec.</returns>
        public static implicit operator int(VideoCodec videoCodec)
        {
            return videoCodec.codec;
        }

        /// <summary>
        /// Creates video codec from the 32-bit integer.
        /// </summary>
        /// <param name="code">32-bit code.</param>
        /// <returns>New codec name.</returns>
        public static explicit operator VideoCodec(int code)
        {
            return new VideoCodec(code);
        }

        /// <summary>
        /// Creates video codec from the 4-character string.
        /// </summary>
        /// <param name="code">4-character string.</param>
        /// <returns>New codec name.</returns>
        /// <exception cref="System.Exception">Invalid string length.</exception>
        public static explicit operator VideoCodec(string code)
        {
            return VideoCodec.FromName(code);
        }

        /// <summary>
        /// Gets the string representation of the codec name.
        /// </summary>
        /// <returns>String representation.</returns>
        public override string ToString()
        {
            unsafe 
            {
                fixed (int* intPtr = &this.codec)
                {
                    sbyte* chPtr = (sbyte*)intPtr;
                    return new string(chPtr, 0, CODEC_NAME_LENGTH);
                }
            }
        }
    }

    /// <summary>
    /// OpenCV capture properties for camera and video.
    /// </summary>
    internal enum CaptureProperty: int
    {
        PosMsec = 0,
        PosFrames = 1,
        FrameWidth = 3,
        FrameHeight = 4,
        FPS = 5,
        FrameCount = 7,

        /************** camera properties ******************/
        Brightness = 10,
        Contrast = 11,
        Saturation = 12,
        Hue = 13,
        Gain = 14,
        Exposure = 15,
        /************** camera properties ******************/

        ConvertRGB = 16
    }

    /// <summary>
    /// OpenCV image load mode.
    /// </summary>
    [Flags]
    internal enum ImageLoadType : int
    {
        /// <summary>
        /// Loads the image as is (including the alpha channel if present) 
        /// </summary>
        Unchanged = -1,

        /// <summary>
        /// Loads the image as an intensity image
        /// </summary>
        Grayscale = 0,

        /// <summary>
        ///  Loads the image in the RGB format
        /// </summary>
        Color = 1,

        /// <summary>
        /// Loads the image of any color
        /// </summary>
        AnyColor = 4,

        /// <summary>
        /// Loads the image of any depth
        /// </summary>
        AnyDepth = 2
    }

    /// <summary>
    /// Internal class for OpenCV core / highgui library invocation.
    /// </summary>
    internal static class CvInvoke
    {
        public const CallingConvention CvCallingConvention = CallingConvention.Cdecl;
        public const string OPENCV_CORE_LIBRARY = "opencv_core2412";
        public const string OPENCV_HIGHGUI_LIBRARY = "opencv_highgui2412";

        #region Core

        [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern void cvReleaseMat(ref CvMat* mat);

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern void cvReleaseImage(ref IplImage* image);
        #endregion

        #region Video reader

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern IntPtr cvCreateCameraCapture(int index);

        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern IntPtr cvCreateFileCapture([MarshalAs(UnmanagedType.LPStr)] string filename);


        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern void cvReleaseCapture(ref IntPtr capture);


        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern int cvGrabFrame(IntPtr capture);

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern IntPtr cvQueryFrame(IntPtr capture);


        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern double cvGetCaptureProperty(IntPtr capture, CaptureProperty propertyId);

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool cvSetCaptureProperty(IntPtr capture, CaptureProperty propertyId, double value);

        public static Size GetImageSize(IntPtr capturePtr)
        {
            return new Size
            {
                Width = (int)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.FrameWidth),
                Height = (int)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.FrameHeight)
            };
        }

        public static bool SetImageSize(IntPtr capturePtr, Size newSize)
        {
            bool success;
            success = CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.FrameWidth, newSize.Width);
            success &= CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.FrameHeight, newSize.Height);

            return success;
        }

        #endregion

        #region Video writer

        /// <summary>
        /// Creates video writer structure.
        /// </summary>
        /// <param name="filename">Name of the output video file.</param>
        /// <param name="fourcc">4-character code of codec used to compress the frames. See <see cref="VideoCodec"/> class.</param>
        /// <param name="fps">Frame rate of the created video stream. </param>
        /// <param name="frameSize">Size of video frames.</param>
        /// <param name="isColor">If true, the encoder will expect and encode color frames, otherwise it will work with grayscale frames </param>
        /// <returns>The video writer</returns>
        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern IntPtr cvCreateVideoWriter([MarshalAs(UnmanagedType.LPStr)] String filename, int fourcc, double fps, Size frameSize, [MarshalAs(UnmanagedType.Bool)] bool isColor);

        /// <summary>
        /// Writes/appends one frame to video file.
        /// </summary>
        /// <param name="writer">video writer structure.</param>
        /// <param name="image">the written frame</param>
        /// <returns>True on success, false otherwise</returns>
        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool cvWriteFrame(IntPtr writer, IntPtr image);

        /// <summary>
        /// Finishes writing to video file and releases the structure.
        /// </summary>
        /// <param name="writer">pointer to video file writer structure</param>
        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public static extern void cvReleaseVideoWriter(ref IntPtr writer);
        #endregion

        #region Image IO

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern IplImage* cvLoadImage([MarshalAs(UnmanagedType.LPStr)] String filename, ImageLoadType loadType);

        //[SuppressUnmanagedCodeSecurity]
        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern bool cvSaveImage([MarshalAs(UnmanagedType.LPStr)] String filename, IplImage* image, IntPtr parameters);

        public const int CV_IMWRITE_JPEG_QUALITY = 1;
        public const int CV_IMWRITE_PNG_COMPRESSION = 16;
        public const int CV_IMWRITE_PXM_BINARY = 32;

        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern CvMat* cvEncodeImage([MarshalAs(UnmanagedType.LPStr)] string ext, CvMat* image, int* parameters = null);

        [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConvention)]
        public unsafe static extern CvMat* cvDecodeImageM(void* buffer, ImageLoadType loadType);

        #endregion Image IO
    }
}


================================================
FILE: Source/IO/IO.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <Platforms>x64</Platforms>
    <AssemblyName>DotImaging.IO</AssemblyName>
    <RootNamespace>DotImaging</RootNamespace>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>
    
  <ItemGroup>
    <ProjectReference Include="..\Image\Image.csproj" />
  </ItemGroup>
    
  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <DocumentationFile>bin\DotImaging.IO.xml</DocumentationFile>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
  </PropertyGroup>
  
  <!-- NuGet --> 
  <PropertyGroup>
    <Version>5.3.0</Version>
    
    <PackageId>DotImaging.IO</PackageId>
    <Description>Loading and saving images and image streams (file, in-memory, camera, video, directory).</Description>
    <PackageTags>image-encode, image-decode, image-load, image-save, image-directory, camera-capture, multiple-camera-capture, video-capture, video-write</PackageTags>

    <Authors>Darko Jurić</Authors>
    <Copyright>Darko Jurić</Copyright>
    <PackageLicenseUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Licence.txt</PackageLicenseUrl>
    <PackageIconUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Logo/logo-small.png</PackageIconUrl>
    <PackageProjectUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</PackageProjectUrl>
    <RepositoryUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</RepositoryUrl>

    <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
    <PackageOutputPath>../../Deploy/NuGet/bin/</PackageOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="runtimes\win10-x64\" />
    <Folder Include="runtimes\ubuntu.16.04-x64\" />

    <Content Include=".nuSpec/readmeIO.txt">
      <PackagePath>Readme.txt</PackagePath>
    </Content>

    <!-- Windows -->
    <Content Include="runtimes\win10-x64\*.dll">
      <Link>runtimes\win10-x64\%(FileName)%(Extension)</Link>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackagePath>runtimes/win10-x64/native/</PackagePath>
    </Content>

    <!-- Linux -->
    <Content Include="runtimes\ubuntu.16.04-x64\*.so*">
      <Link>runtimes\ubuntu.16.04-x64\%(FileName)%(Extension)</Link>
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
      <PackagePath>runtimes/ubuntu.16.04-x64/native/</PackagePath>
    </Content>
  </ItemGroup>
</Project>


================================================
FILE: Source/IO/ImageIO.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;

namespace DotImaging
{
    /// <summary>
    /// Provides methods for image saving and loading
    /// </summary>
    public static class ImageIO 
    {
        #region Load (file)

        private unsafe static IImage load(string fileName, ImageLoadType imageLoadType)
        {
            var iplImagePtr = CvInvoke.cvLoadImage(fileName, imageLoadType);
            var image = (*iplImagePtr).AsImage((_) =>
            {
                if (iplImagePtr == null) return;
                CvInvoke.cvReleaseImage(ref iplImagePtr);
            });

            return image;
        }

        /// <summary>
        /// Loads an image with the specified path and name as it is.
        /// </summary>
        /// <param name="fileName">Image file name.</param>
        /// <returns>Image.</returns>
        public unsafe static IImage LoadUnchanged(this string fileName)
        {
            return load(fileName, ImageLoadType.Unchanged);
        }

        /// <summary>
        /// Loads an image with the specified path and name and performs and RGB conversion.
        /// </summary>
        /// <param name="fileName">Image filename.</param>
        /// <returns>Image.</returns>
        public unsafe static Bgr<byte>[,] LoadColor(this string fileName)
        {
            Bgr<byte>[,] im = null;
            using (var uIm = load(fileName, ImageLoadType.Color) as Image<Bgr<byte>>)
                im = uIm.Clone();

            return im;
        }

        /// <summary>
        /// Loads an image with the specified path and name and performs and gray conversion.
        /// </summary>
        /// <param name="fileName">Image filename.</param>
        /// <returns>Image.</returns>
        public unsafe static Gray<byte>[,] LoadGray(this string fileName)
        {
            Gray<byte>[,] im = null;
            using (var uIm = load(fileName, ImageLoadType.Grayscale) as Image<Gray<byte>>)
                im = uIm.Clone();

            return im;
        }

        #endregion

        #region Save (file)

        /// <summary>
        /// Saves the provided image. If the image has non-supported color or depth false value is returned.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Filename.</param>
        /// <returns>True if the image is saved, false otherwise.</returns>
        public unsafe static bool TrySave(IImage image, string fileName)
        {
            IplImage iplImage = default(IplImage);
            try
            {
                iplImage = image.AsCvIplImage();
            }
            catch 
            {
                return false;
            }

            CvInvoke.cvSaveImage(fileName, &iplImage, IntPtr.Zero);
            return true;
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <typeparam name="TColor">Image color.</typeparam>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        private unsafe static void Save<TColor>(this Image<TColor> image, string fileName)
            where TColor : unmanaged, IColor
        {
            var iplImage = image.AsCvIplImage();
            CvInvoke.cvSaveImage(fileName, &iplImage, IntPtr.Zero);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <typeparam name="TColor">Image color.</typeparam>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        private unsafe static void Save<TColor>(this TColor[,] image, string fileName)
            where TColor: unmanaged, IColor
        {
            using (var img = image.Lock())
            {
                var iplImage = img.AsCvIplImage();
                CvInvoke.cvSaveImage(fileName, &iplImage, IntPtr.Zero);
            }
        }

        #region Save-gray

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<byte>[,] image, string fileName)
        {
            image.Save<Gray<byte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<sbyte>[,] image, string fileName)
        {
            image.Save<Gray<sbyte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<short>[,] image, string fileName)
        {
            image.Save<Gray<short>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<ushort>[,] image, string fileName)
        {
            image.Save<Gray<ushort>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<int>[,] image, string fileName)
        {
            image.Save<Gray<int>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<float>[,] image, string fileName)
        {
            image.Save<Gray<float>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Gray<double>[,] image, string fileName)
        {
            image.Save<Gray<double>>(fileName);
        }

        #endregion

        #region Save-bgr

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<byte>[,] image, string fileName)
        {
            image.Save<Bgr<byte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<sbyte>[,] image, string fileName)
        {
            image.Save<Bgr<sbyte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<short>[,] image, string fileName)
        {
            image.Save<Bgr<short>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<ushort>[,] image, string fileName)
        {
            image.Save<Bgr<ushort>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<int>[,] image, string fileName)
        {
            image.Save<Bgr<int>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<float>[,] image, string fileName)
        {
            image.Save<Bgr<float>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgr<double>[,] image, string fileName)
        {
            image.Save<Bgr<double>>(fileName);
        }

        #endregion

        #region Save-bgra

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<byte>[,] image, string fileName)
        {
            image.Save<Bgra<byte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<sbyte>[,] image, string fileName)
        {
            image.Save<Bgra<sbyte>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<short>[,] image, string fileName)
        {
            image.Save<Bgra<short>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<ushort>[,] image, string fileName)
        {
            image.Save<Bgra<ushort>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<int>[,] image, string fileName)
        {
            image.Save<Bgra<int>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<float>[,] image, string fileName)
        {
            image.Save<Bgra<float>>(fileName);
        }

        /// <summary>
        /// Saves the specified image.
        /// </summary>
        /// <param name="image">Image to save.</param>
        /// <param name="fileName">Image filename.</param>
        public static void Save(this Bgra<double>[,] image, string fileName)
        {
            image.Save<Bgra<double>>(fileName);
        }

        #endregion

        #endregion

        #region Encode

        /// <summary>
        /// Encodes the specified image into the Jpeg byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="jpegQuality">Jpeg quality [0..100] where 100 is the highest quality.</param>
        /// <returns>Jpeg byte array.</returns>
        public static byte[] EncodeAsJpeg(this Gray<byte>[,] image, int jpegQuality = 95)
        {
            return encodeAsJpeg(image, jpegQuality);
        }

        /// <summary>
        /// Encodes the specified image into the Jpeg byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="jpegQuality">Jpeg quality [0..100] where 100 is the highest quality.</param>
        /// <returns>Jpeg byte array.</returns>
        public static byte[] EncodeAsJpeg(this Bgr<byte>[,] image, int jpegQuality = 95)
        {
            return encodeAsJpeg(image, jpegQuality);
        }

        /// <summary>
        /// Encodes the specified image into the Jpeg byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="jpegQuality">Jpeg quality [0..100] where 100 is the highest quality.</param>
        /// <returns>Jpeg byte array.</returns>
        public static byte[] EncodeAsJpeg(this Gray<ushort>[,] image, int jpegQuality = 95)
        {
            return encodeAsJpeg(image, jpegQuality);
        }

        /// <summary>
        /// Encodes the specified image into the Jpeg byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="jpegQuality">Jpeg quality [0..100] where 100 is the highest quality.</param>
        /// <returns>Jpeg byte array.</returns>
        public static byte[] EncodeAsJpeg(this Bgr<ushort>[,] image, int jpegQuality = 95)
        {
            return encodeAsJpeg(image, jpegQuality);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Gray<byte>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Bgr<byte>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Bgra<byte>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Gray<ushort>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Bgr<ushort>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the PNG byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="pngCompression">PNG compression level [0..9] where 9 is the highest compression.</param>
        /// <returns>PNG byte array.</returns>
        public static byte[] EncodeAsPng(this Bgra<ushort>[,] image, int pngCompression = 3)
        {
            return encodeAsPng(image, pngCompression);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Gray<byte>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Bgr<byte>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Bgra<byte>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Gray<ushort>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Bgr<ushort>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        /// <summary>
        /// Encodes the specified image into the specified image type byte array.
        /// </summary>
        /// <param name="image">Image to encode.</param>
        /// <param name="extension">Image type extension (.bmp, .png, .jpg)</param>
        /// <returns>Image type byte array.</returns>
        public static byte[] Encode(this Bgra<ushort>[,] image, string extension)
        {
            return encode(image, extension, null);
        }

        static byte[] encodeAsJpeg<TColor>(TColor[,] image, int jpegQuality = 95)
            where TColor : unmanaged, IColor
        {
            if (jpegQuality < 0 || jpegQuality > 100)
                throw new ArgumentOutOfRangeException("Jpeg quality must be in range: 0-100.");

            int[] parameters = new int[] { CvInvoke.CV_IMWRITE_JPEG_QUALITY, jpegQuality, 0 };
            return encode(image, ".jpg", parameters);
        }

        static byte[] encodeAsPng<TColor>(TColor[,] image, int pngCompression = 3)
            where TColor : unmanaged, IColor
        {
            if (pngCompression < 0 || pngCompression > 9)
                throw new ArgumentOutOfRangeException("Png compression must be in range: 0-9.");

            int[] parameters = new int[] { CvInvoke.CV_IMWRITE_PNG_COMPRESSION, pngCompression, 0 };
            return encode(image, ".png", parameters);
        }

        static unsafe byte[] encode<TColor>(TColor[,] image, string extension, int[] parameters)
           where TColor : unmanaged, IColor
        {
            CvMat* matEncoded; //a single-row image

            using (var uImg = image.Lock())
            {
                fixed (int* paramsPtr = parameters)
                {
                    var mat = uImg.AsCvMat();
                    matEncoded = CvInvoke.cvEncodeImage(extension, &mat, paramsPtr);
                }
            }

            byte[] imEncoded = new byte[matEncoded->Step * matEncoded->Height];
            fixed (byte* arrPtr = &imEncoded[0])
            {
                Copy.UnsafeCopy(matEncoded->ImageData, (IntPtr)arrPtr, imEncoded.Length);
            }

            CvInvoke.cvReleaseMat(ref matEncoded); //TODOD: check if this deferences the image
            return imEncoded;
        }

        #endregion

        #region Decode

        /// <summary>
        /// Decodes (and converts if necessary) an image as color image using the specified byte array.
        /// </summary>
        /// <param name="encodedImage">Encoded image.</param>
        /// <returns>Decoded image.</returns>
        public unsafe static Bgr<byte>[,] DecodeAsColorImage(this byte[] encodedImage)
        {
            return decodeImage<Bgr<byte>>(encodedImage, ImageLoadType.Color);
        }

        /// <summary>
        /// Decodes (and converts if necessary) an image as gray image using the specified byte array.
        /// </summary>
        /// <param name="encodedImage">Encoded image.</param>
        /// <returns>Decoded image.</returns>
        public unsafe static Gray<byte>[,] DecodeAsGrayImage(this byte[] encodedImage)
        {
            return decodeImage<Gray<byte>>(encodedImage, ImageLoadType.Grayscale);
        }

        unsafe static TColor[,] decodeImage<TColor>(byte[] encodedImage, ImageLoadType loadType)
            where TColor : unmanaged, IColor
        {
            CvMat* matDecoded;
            fixed (byte* encodedImPtr = encodedImage)
            {
                CvMat mat = CvMat.FromUserData((IntPtr)encodedImPtr, encodedImage.Length, 1, encodedImage.Length, CvMat.CvChannelDepth.CV_8U, 1);
                matDecoded = CvInvoke.cvDecodeImageM(&mat, ImageLoadType.Color);
            }

            var imDecoded = (*matDecoded).ToArray<TColor>();
            CvInvoke.cvReleaseMat(ref matDecoded);

            return imDecoded;
        }

        #endregion
    }
}


================================================
FILE: Source/IO/Readers/CameraCapture.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Drawing;

namespace DotImaging
{
    /// <summary>
    /// Represents camera stream-able source and provides functions and properties to access a device in a stream-able way.
    /// </summary>
    public class CameraCapture: VideoCaptureBase
    {
        int cameraIdx = 0;

        /// <summary>
        /// Creates capture from camera.
        /// </summary>
        /// <param name="cameraIdx">Camera index.</param>
        public CameraCapture(int cameraIdx = 0)
        {
            this.cameraIdx = cameraIdx;
            this.CanSeek = false;
            this.IsLiveStream = true;
            this.Open(); //to enable property change
        }

        /// <summary>
        /// Opens the camera stream.
        /// </summary>
        public override void Open()
        {
            if (capturePtr != IntPtr.Zero)
                return;
            
            capturePtr = CvInvoke.cvCreateCameraCapture(cameraIdx);
            if (capturePtr == IntPtr.Zero)
                throw new Exception("Cannot open camera stream! It seems that camera device can not be found.");
        }

        /// <summary>
        /// Gets or sets the brightness of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Brightness
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Brightness); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Brightness, value); }
        }

        /// <summary>
        /// Gets or sets the contrast of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Contrast
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Contrast); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Contrast, value); }
        }

        /// <summary>
        /// Gets or sets the exposure of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Exposure
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Exposure); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Exposure, value); }
        }

        /// <summary>
        /// Gets or sets the gain of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Gain
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Gain); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Gain, value); }
        }

        /// <summary>
        /// Gets or sets the hue of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Hue
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Hue); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Hue, value); }
        }

        /// <summary>
        /// Gets or sets the saturation of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public double Saturation
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.Saturation); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.Saturation, value); }
        }

        /// <summary>
        /// Gets or sets the frame size of the camera.
        /// </summary>
        public new Size FrameSize
        {
            get { return CvInvoke.GetImageSize(capturePtr); }
            set { CvInvoke.SetImageSize(capturePtr, value); }
        }

        /// <summary>
        /// Gets or sets the frame rate of the camera.
        /// <para>If the property is not supported by device 0 will be returned.</para>
        /// </summary>
        public new double FrameRate
        {
            get { return CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.FPS); }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.FPS, value); }
        }

        /// <summary>
        /// Gets the available device count.
        /// <para>Warning: the function closes existing streams, so use it before any camera capture object is created.</para>
        /// </summary>
        public static int CameraCount
        {
            get
            {
                int cameraIdx = 0;
                while (true)
                {
                    var capturePtr = CvInvoke.cvCreateCameraCapture(cameraIdx);
                    if (capturePtr != IntPtr.Zero)
                    {
                        CvInvoke.cvReleaseCapture(ref capturePtr);
                        cameraIdx++;
                    }
                    else
                        break;
                }

                return cameraIdx;
            }
        }
    }
}


================================================
FILE: Source/IO/Readers/FileCapture.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.IO;
using System.Linq;

namespace DotImaging
{
    /// <summary>
    /// Provides functions and properties to access video file in a streamable way.
    /// </summary>
    public class FileCapture: VideoCaptureBase
    {
        private static readonly string[] supportedRemoteFiles = new string[] { ".mp4", ".webm" };
        private static readonly string[] supportedLocalFiles = new string[] { ".mp4", ".avi", ".divx", ".webm", ".wmv" };

        string fileName = null;

        /// <summary>
        /// Creates capture from video file.
        /// </summary>
        /// <param name="sourceName">
        /// Local file, http uri, ftp uri or a named pipe.
        /// <para>In case of named pipe use: String.Format(@"\\.\pipe\{0}", pipeName) where pipeName is the name of the pipe.</para>
        /// </param>
        public FileCapture(string sourceName)
        {
            if (sourceName.Contains(@"\\.\pipe\"))
            {
                this.CanSeek = false;
            }
            else if (Uri.IsWellFormedUriString(sourceName, UriKind.Absolute))
            {
                var fileExt = Path.GetExtension(sourceName);
                if (supportedRemoteFiles.Any(x => x.Equals(fileExt.ToLower())) == false)
                    throw new UriFormatException(String.Format("Uri must point to a supported video file ({0}).", String.Join(", ", supportedRemoteFiles)));

                this.CanSeek = true;
            }
            else
            {
                if (!File.Exists(sourceName))
                    throw new FileNotFoundException(String.Format("The file {0} can not be found.", sourceName));

                var fileExt = Path.GetExtension(sourceName);
                if (supportedLocalFiles.Any(x => x.Equals(fileExt.ToLower())) == false)
                    throw new UriFormatException(String.Format("File must be a supported video file ({0}).", String.Join(", ", supportedLocalFiles)));

                this.CanSeek = true;
            }
       
            this.fileName = sourceName;
            this.Open(); //to enable property change
        }

        /// <summary>
        /// Opens the video file stream.
        /// </summary>
        public override void Open()
        {
            if (capturePtr != IntPtr.Zero)
                return;

            capturePtr = CvInvoke.cvCreateFileCapture(fileName);
            if (capturePtr == IntPtr.Zero)
                throw new Exception("Cannot open FileStream!");
        }

        /// <summary>
        /// Gets the current position in the stream as frame offset.
        /// </summary>
        public override long Position
        {
            get { return (long)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.PosFrames); }
            protected set { }  
        }

        /// <summary>
        /// Sets the position within the current stream.
        /// <para>Warning: the underlying OpenCV function seeks to nearest key-frame, therefore the seek operation may not be frame-accurate.</para>
        /// </summary>
        /// <param name="offset">A frame index offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type System.IO.SeekOrigin indicating the reference point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        public override long Seek(long offset, System.IO.SeekOrigin origin = SeekOrigin.Current)
        { 
            var frameIndex = base.Seek(offset, origin);
            CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.PosFrames, frameIndex);

            return Position;
        }
    }
}


================================================
FILE: Source/IO/Readers/ImageDirectoryCapture.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace DotImaging
{
    /// <summary>
    /// Represents directory stream-able source and provides functions and properties to access data in a stream-able way.
    /// </summary>
    public class ImageDirectoryCapture : ImageStreamReader
    {
        long currentFrame = 0;

        #region Initialization

        /// <summary>
        /// Creates an instance of <see cref="ImageDirectoryCapture"/>.
        /// </summary>
        /// <param name="dirPath">The directory path.</param>
        /// <param name="searchPattern">The image search pattern.</param>
        /// <param name="useNaturalSorting">Use natural sorting, otherwise raw image order is used.</param>
        /// <param name="recursive">If true searches the current directory and all subdirectories. Otherwise, only top directory is searched.</param>
        /// <exception cref="DirectoryNotFoundException">Directory can not be found.</exception>
        public ImageDirectoryCapture(string dirPath, string searchPattern, bool useNaturalSorting = true, bool recursive = false)
            : this(dirPath, new string[] { searchPattern }, useNaturalSorting, recursive)
        { }

         /// <summary>
        /// Creates an instance of <see cref="ImageDirectoryCapture"/>.
        /// </summary>
        /// <param name="dirPath">The directory path.</param>
        /// <param name="searchPatterns">The image search patterns.</param>
        /// <param name="useNaturalSorting">Use natural sorting, otherwise raw image order is used.</param>
        /// <param name="recursive">If true searches the current directory and all subdirectories. Otherwise, only top directory is searched.</param>
        /// <exception cref="DirectoryNotFoundException">Directory can not be found.</exception>
        public ImageDirectoryCapture(string dirPath, string[] searchPatterns, bool useNaturalSorting = true, bool recursive = false)
        {
            FileReadFunction = ImageIO.LoadUnchanged;

            if (Directory.Exists(dirPath) == false)
                throw new DirectoryNotFoundException(String.Format("Dir: {0} cannot be found!", dirPath));

            DirectoryInfo directoryInfo = new DirectoryInfo(dirPath); 

            this.IsLiveStream = false;
            this.CanSeek = true;
            this.DirectoryInfo = directoryInfo;

            var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;

            if (useNaturalSorting)
            {
                this.FileInfos = directoryInfo.EnumerateFiles(searchPatterns, searchOption)
                                  .OrderBy(f => f.FullName, new NaturalSortComparer()) //in case of problems replace f.FullName with f.Name
                                  .ToArray();
            }
            else
            {
                this.FileInfos = directoryInfo.EnumerateFiles(searchPatterns, searchOption)
                                  .ToArray();
            }
        }

        #endregion

        /// <summary>
        /// Open the current stream. This overload does not do anything.
        /// </summary>
        public override void Open() { }

        /// <summary>
        /// Closes the current stream. This overload resets position to zero.
        /// </summary>
        public override void Close()
        {
            currentFrame = 0;
        }

        object syncObj = new object();
        /// <summary>
        /// Reads an image from the stream.
        /// </summary>
        /// <param name="image">Read image.</param>
        /// <returns>True if the reading operation was successful, false otherwise.</returns>
        protected override bool ReadInternal(out IImage image)
        {
            lock (syncObj)
            {
                image = default(IImage);

                if (this.Position >= this.Length)
                    return false;

                image = FileReadFunction(FileInfos[currentFrame].FullName);
                currentFrame++;
            }

            return true;
        }

        /// <summary>
        /// Gets the total number of files in the specified directory which match the specified search criteria.
        /// </summary>
        public override long Length { get { return FileInfos.Length; } }

        /// <summary>
        /// Gets the current position within the stream.
        /// </summary>
        public override long Position { get { return currentFrame; } }

        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A frame index offset relative to the origin parameter.</param>
        /// <param name="origin">A value of type <see cref="System.IO.SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
        /// <returns>The new position within the current stream.</returns>
        public override long Seek(long offset, SeekOrigin origin = SeekOrigin.Current)
        {
            this.currentFrame = base.Seek(offset, origin);
            return Math.Max(0, Math.Min(currentFrame, this.Length));
        }


        #region Specific function

        /// <summary>
        /// Gets the source directory info.
        /// </summary>
        public DirectoryInfo DirectoryInfo
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the ordered set of files which compose the current image directory stream.
        /// </summary>
        public FileInfo[] FileInfos
        {
            get;
            private set;
        }

        /// <summary>
        /// Gets the current image file name.
        /// <para>If the position of the stream is equal to the stream length null is returned.</para>
        /// </summary>
        public string CurrentImageName
        {
            get { return (this.Position < FileInfos.Length) ? FileInfos[this.Position].FullName : null; }
        }

        Func<string, IImage> fileReadFunction;
        /// <summary>
        /// Gets or sets the file read function.
        /// <para>A default reading function loads image as it is (unchanged).</para>
        /// </summary>
        public Func<string, IImage> FileReadFunction
        {
            get { return fileReadFunction; }
            set
            {
                if (value == null)
                    new ArgumentNullException("File read function can not be null.");

                fileReadFunction = value;
            }
        }

        #endregion
    }
}


================================================
FILE: Source/IO/Readers/VideoCaptureBase.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Drawing;

namespace DotImaging
{
    /// <summary>
    /// Represents the base class for video capture that shares common functions and properties with camera and file capture. 
    /// </summary>
    public abstract class VideoCaptureBase : ImageStreamReader
    {
        /// <summary>
        /// Internal OpenCV pointer for the capture object.
        /// </summary>
        protected IntPtr capturePtr;

        /// <summary>
        /// Releases all resources allocated by capture.
        /// </summary>
        public override void Close()
        {
            if (capturePtr != IntPtr.Zero)
                CvInvoke.cvReleaseCapture(ref capturePtr);
        }

        object syncObj = new object();
        /// <summary>
        /// Reads the next image in the stream and advances the position by one.
        /// </summary>
        /// <param name="image">Read image.</param>
        /// <returns>True if the reading operation was successful, false otherwise.</returns>
        protected override bool ReadInternal(out IImage image)
        {
            bool status = false;
            image = default(IImage);

            lock (syncObj)
            {
                IntPtr cvFramePtr;
                cvFramePtr = CvInvoke.cvQueryFrame(capturePtr);

                if (cvFramePtr != IntPtr.Zero)
                {
                    image = IplImage.FromPointer(cvFramePtr).AsImage();
                    this.Position++;
                    status = true;
                }
            }

            return status;
        }

        /// <summary>
        /// Gets the length in number of frames.
        /// </summary>
        public override long Length
        {
            get { return (long)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.FrameCount); }
        }

        /// <summary>
        /// Gets or sets whether to force conversion of an input image to Bgr color type.
        /// </summary>
        public bool ConvertRgb
        {
            get { return (int)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.ConvertRGB) != 0; }
            set { CvInvoke.cvSetCaptureProperty(capturePtr, CaptureProperty.ConvertRGB, value ? 0 : 1); }
        }

        /// <summary>
        /// Gets the frame size.
        /// </summary>
        public Size FrameSize
        {
            get { return CvInvoke.GetImageSize(capturePtr); }
        }

        /// <summary>
        /// Gets the frame rate.
        /// </summary>
        public float FrameRate
        {
            get { return (float)CvInvoke.cvGetCaptureProperty(capturePtr, CaptureProperty.FPS); }
        }
    }
}


================================================
FILE: Source/IO/Utilities/NaturalSortComparer.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace DotImaging
{
    /// <summary>
    /// Provides functions for natural string comparison.
    /// Reference: <seealso cref="https://www.codeproject.com/Articles/22517/Natural-Sort-Comparer"/>.
    /// </summary>
    class NaturalSortComparer: IComparer<string>
    {
        private bool isAscending;

        /// <summary>
        /// Creates a new instance of <see cref="NaturalSortComparer"/>.
        /// </summary>
        /// <param name="inAscendingOrder">Sorts in ascending order, otherwise descending.</param>
        public NaturalSortComparer(bool inAscendingOrder = true)
        {
            this.isAscending = inAscendingOrder;
        }

        #region IComparer<string> Members

        /// <summary>
        /// Compares two strings.
        /// </summary>
        /// <param name="x">First string.</param>
        /// <param name="y">Second string.</param>
        /// <returns>0 - the same objects, -1, +1 otherwise depending whether the first string precedes the second one or not.</returns>
        public int Compare(string x, string y)
        { 
            throw new NotImplementedException();
        }

        #endregion

        #region IComparer<string> Members

        int IComparer<string>.Compare(string x, string y)
        {
            if (x == y)
                return 0;

            string[] x1, y1;

            if (!table.TryGetValue(x, out x1))
            {
                x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)");
                table.Add(x, x1);
            }

            if (!table.TryGetValue(y, out y1))
            {
                y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)");
                table.Add(y, y1);
            }

            int returnVal;

            for (int i = 0; i < x1.Length && i < y1.Length; i++)
            {
                if (x1[i] != y1[i])
                {
                    returnVal = PartCompare(x1[i], y1[i]);
                    return isAscending ? returnVal : -returnVal;
                }
            }

            if (y1.Length > x1.Length)
            {
                returnVal = 1;
            }
            else if (x1.Length > y1.Length)
            {
                returnVal = -1;
            }
            else
            {
                returnVal = 0;
            }

            return isAscending ? returnVal : -returnVal;
        }

        private static int PartCompare(string left, string right)
        {
            int x, y;
            if (!int.TryParse(left, out x))
                return left.CompareTo(right);

            if (!int.TryParse(right, out y))
                return left.CompareTo(right);

            return x.CompareTo(y);
        }

        #endregion

        private Dictionary<string, string[]> table = new Dictionary<string, string[]>();
    }
}


================================================
FILE: Source/IO/Utilities/PathExtensions.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections.Generic;
using System.IO;

namespace DotImaging
{
    /// <summary>
    /// <para>Defined functions can be used as object extensions.</para>
    /// Provides methods for string which is treated as file and directory path.
    /// </summary>
    static class PathExtensions
    {
        /// <summary>
        /// Returns an enumerable collection of file information that matches a specified search pattern and search subdirectory option.
        /// </summary>
        /// <param name="dirInfo">Directory info.</param>
        /// <param name="searchPatterns">The search strings (e.g. new string[]{ ".jpg", ".bmp" }</param>
        /// <param name="searchOption">
        /// One of the enumeration values that specifies whether the search operation
        /// should include only the current directory or all subdirectories. The default
        /// value is <see cref="System.IO.SearchOption.TopDirectoryOnly"/>.
        ///</param>
        /// <returns>An enumerable collection of files that matches <paramref name="searchPatterns"/> and <paramref name="searchOption"/>.</returns>
        public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo dirInfo, string[] searchPatterns, SearchOption searchOption = SearchOption.TopDirectoryOnly)
        {
            var fileInfos = new List<FileInfo>();
            foreach (var searchPattern in searchPatterns)
            {
                var dirFileInfos = dirInfo.EnumerateFiles(searchPattern, searchOption);
                fileInfos.AddRange(dirFileInfos);
            }

            return fileInfos;
        }

    }
}


================================================
FILE: Source/IO/Writers/ImageWriterExtension.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.IO;

namespace DotImaging
{

    /// <summary>
    /// Provides extensions for image extraction from image streams.
    /// </summary>
    public static class ImageWriterExtension
    {
        /// <summary>
        /// Reads the image source and save the extracted images to the specified folder.
        /// </summary>
        /// <param name="imageSource">Image stream reader.</param>
        /// <param name="outputDir">Output directory.</param>
        /// <param name="fileNameFormat">Image file name format.</param>
        /// <param name="onFrameCompletition">Progress function executed after a frame is saved.</param>
        public static void SaveFrames(this ImageStreamReader imageSource, string outputDir, 
                                      string fileNameFormat = "img-{0:000}.png", 
                                      Action<float> onFrameCompletition = null)
        {
            if (!Directory.Exists(outputDir))
                Directory.CreateDirectory(outputDir);

            if (imageSource.CanSeek)
                imageSource.Seek(0, SeekOrigin.Begin);

            var idx = 0;
            foreach (var frame in imageSource) //use video stream as IEnumerable<IImage> (must support seek operation)
            {
                if (frame != null) //some videos skip key frames (discard those frames)
                {
                    var path = Path.Combine(outputDir, String.Format(fileNameFormat, idx));
                    ImageIO.TrySave(frame, path); //TODO-noncritical: add compression options
                }

                if(onFrameCompletition != null)
                    onFrameCompletition((float)(idx + 1) / imageSource.Length);

                idx++;
            }
        }
    }
}


================================================
FILE: Source/IO/Writers/VideoWriter.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Drawing;

namespace DotImaging
{
    /// <summary>
    /// Video writer that writes images into video file.
    /// </summary>
    public class VideoWriter : ImageStreamWriter
    {
        object syncObj = new object();
        IntPtr videoObjPtr = IntPtr.Zero;

        /// <summary>
        /// Gets the output file name.
        /// </summary>
        public string OutputFileName { get; private set; }

        /// <summary>
        /// Gets whether the frame must consist of 3-channels (color) or from just one (grayscale).
        /// </summary>
        public bool ColorFrames { get; private set; }

        /// <summary>
        /// Gets the codec used to encode frames.
        /// </summary>
        public VideoCodec Codec { get; private set; }

        /// <summary>
        /// Gets the number of frames per second.
        /// </summary>
        public float FrameRate { get; private set; }

        /// <summary>
        /// Gets the frame size.
        /// </summary>
        public Size FrameSize { get; private set; }

        /// <summary>
        /// Creates new video writer (with default codec).
        /// </summary>
        /// <param name="fileName">Video file name.</param>
        /// <param name="frameSize">Video frame size.</param>
        /// <param name="fps">Specifies the number of frames per second.</param>
        /// <param name="isColor">Specifies whether the image is color image (3 channels) or grayscale image (one channel).</param>
        public VideoWriter(string fileName, Size frameSize, float fps = 30, bool isColor = true)
            : this(fileName, frameSize, fps, isColor, VideoCodec.MotionJpeg)
        { }

        /// <summary>
        /// Creates new video writer.
        /// </summary>
        /// <param name="fileName">Video file name.</param>
        /// <param name="frameSize">Video frame size.</param>
        /// <param name="fps">Specifies the number of frames per second.</param>
        /// <param name="isColor">Specifies whether the image is color image (3 channels) or grayscale image (one channel).</param>
        /// <param name="videoCodec">Specifies used codec for video encoding.</param>
        public VideoWriter(string fileName, Size frameSize, float fps, bool isColor, VideoCodec videoCodec)
        {
            this.CanSeek = false;
            this.IsLiveStream = true;

            this.OutputFileName = fileName;
            this.ColorFrames = isColor;
            this.Codec = videoCodec;
            this.FrameSize = frameSize;
            this.FrameRate = fps;

            this.Open(); //to enable property change
        }

        /// <summary>
        /// Opens the video file stream.
        /// </summary>
        public override void Open()
        {
            if (videoObjPtr != IntPtr.Zero)
                return;

            videoObjPtr = CvInvoke.cvCreateVideoWriter(OutputFileName, (int)Codec, FrameRate, FrameSize, ColorFrames);
            if (videoObjPtr == IntPtr.Zero)
                throw new Exception(String.Format("Cannot open FileStream! Please check that the selected codec ({0}) is supported.", Codec));
        }

        /// <summary>
        /// Gets the current position in the stream as frame offset.
        /// </summary>
        public override long Position
        {
            get;
            protected set;
        }

        /// <summary>
        /// Gets the current stream length which is not constant and is the same as position.
        /// </summary>
        public override long Length
        {
            get { return this.Position; }
        }

        /// <summary>
        /// Writes the provided image to the stream.
        /// </summary>
        /// <param name="image">Image to write.</param>
        /// <returns>True, if the operation was successful, false otherwise.</returns>
        protected unsafe override bool WriteInternal(IImage image)
        {
            bool isSuccessful;

            lock (syncObj)
            {
                if (image.ColorInfo.ChannelCount == 3 && !ColorFrames)
                    throw new Exception("Image must be grayscale!");

                if (image.ColorInfo.ChannelCount == 1 && ColorFrames)
                    throw new Exception("Image must be color!");

                if (image.ColorInfo.ChannelCount != 3 && ColorFrames)
                    throw new Exception("Color images must have 3 channels!");

                if (!image.Size.Equals(FrameSize))
                    throw new Exception("Input image must be the same size as defined frame size!");

                this.Position++;

                var iplImg = image.AsCvIplImage();
                IplImage* iplImgPtr = (IplImage*)&iplImg;

                isSuccessful = CvInvoke.cvWriteFrame(videoObjPtr, (IntPtr)iplImgPtr);
            }

            return isSuccessful;
        }

        /// <summary>
        /// Closes video writer.
        /// <para>Use dispose method to remove any additional resources.</para>
        /// </summary>
        public override void Close()
        {
            if (videoObjPtr != IntPtr.Zero)
                CvInvoke.cvReleaseVideoWriter(ref videoObjPtr);
        }
    }
}

================================================
FILE: Source/IO.Web/.nuSpec/readmeIO.Web.txt
================================================
 Provides support for image or video download/streaming (direct video link or Youtube links).

1) image loading:
  
   new Uri("http://vignette3.wikia.nocookie.net/disney/images/5/5d/Lena_headey_.jpg")
        .GetBytes()
        .DecodeAsColorImage()
	.Show(); //requires UI package

2) video streaming:

    var sourceName = String.Empty;

    var pipeName = new Uri("https://www.youtube.com/watch?v=Vpg9yizPP_g").NamedPipeFromYoutubeUri(); //Youtube
    sourceName = String.Format(@"\\.\pipe\{0}", pipeName);
    
    //sourceName = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"; //direct http streaming 

    //------------------------------------------------------------------
    ImageStreamReader reader = new FileCapture(sourceName);
    reader.Open();

    //seek if you can
    if(reader.CanSeek)
       reader.Seek((int)(reader.Length * 0.25), System.IO.SeekOrigin.Begin);

    //read video frames
    Bgr<byte>[,] frame = null;
    do
    {
	reader.ReadTo(ref frame);
	if (frame == null)
		break;

	frame.Show(scaleForm: true);
	((double)reader.Position / reader.Length).Progress();
     }
     while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape));


3) video download:

   string fileExtension;
   pipeName = new Uri("https://www.youtube.com/watch?v=Vpg9yizPP_g").NamedPipeFromYoutubeUri(out fileExtension); //Youtube
   pipeName.SaveNamedPipeStream("out" + fileExtension);


Discover more types as you type :)


================================================
FILE: Source/IO.Web/IO.Web.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">  
  <PropertyGroup>
    <AssemblyName>DotImaging.IO.Web</AssemblyName>
    <RootNamespace>DotImaging</RootNamespace>
    <Platforms>AnyCPU</Platforms>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="VideoLibrary" Version="2.0.3" />
  </ItemGroup>
	
  <ItemGroup>
    <ProjectReference Include="..\Image\Image.csproj" />
  </ItemGroup> 

  <PropertyGroup Condition="'$(Configuration)'=='Release'">
    <DocumentationFile>bin\DotImaging.IO.Web.xml</DocumentationFile>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
  </PropertyGroup>

  <!-- NuGet -->
  <PropertyGroup>
    <Version>5.3.0</Version>

    <PackageId>DotImaging.IO.Web</PackageId>
    <Description>Image or video download/streaming (direct video link or Youtube links).</Description>
    <PackageTags>web-image, image-download, video-download, video-streaming, Youtube, web-video</PackageTags>

    <Authors>Darko Jurić</Authors>
    <Copyright>Darko Jurić</Copyright>
    <PackageLicenseUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Licence.txt</PackageLicenseUrl>
    <PackageIconUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/master/Deploy/Logo/logo-small.png</PackageIconUrl>
    <PackageProjectUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</PackageProjectUrl>
    <RepositoryUrl>https://raw.githubusercontent.com/dajuric/dot-imaging/</RepositoryUrl>

    <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
    <PackageOutputPath>../../Deploy/NuGet/bin/</PackageOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <Content Include=".nuSpec/readmeIO.Web.txt">
      <PackagePath>Readme.txt</PackagePath>
    </Content>
  </ItemGroup>
</Project>


================================================
FILE: Source/IO.Web/NamedPipeExtensions.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.IO;
using System.Threading.Tasks;
using System.IO.Pipes;
using System.Net;
using VideoLibrary;

namespace DotImaging
{
    /// <summary>
    /// Provides named pipe creation extension for Uri, string and Stream.
    /// </summary>
    public static class NamedPipeExtensions
    {
        #region Reading

        /// <summary>
        /// Creates a new named pipe from a file stream.
        /// </summary>
        /// <param name="fileName">File name.</param>
        /// <param name="namedPipeName">Named pipe.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <returns>Pipe name.</returns>
        public static string NamedPipeFromFileName(this string fileName, string namedPipeName = "filePipe", Func<float, bool> onProgress = null)
        {
            if (File.Exists(fileName))
                throw new ArgumentException("The provided file does not exist.", nameof(fileName));

            Stream source = File.OpenRead(fileName);

            return NamedPipeFromStreamAsync(source, namedPipeName, onProgress, () =>
            {
                source.Dispose();
            });
        }

        /// <summary>
        /// Creates a new named pipe from a link (video-link if used in conjunction with IO package).
        /// </summary>
        /// <param name="uri">Uri to web file.</param>
        /// <param name="namedPipeName">Named pipe.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <returns>Pipe name.</returns>
        public static string NamedPipeFromVideoUri(this Uri uri, string namedPipeName = "webPipe", Func<float, bool> onProgress = null)
        {
            var request = (HttpWebRequest)WebRequest.Create(uri.AbsoluteUri);
            WebResponse response = request.GetResponse();
            Stream source = response.GetResponseStream();

            return NamedPipeFromStreamAsync(source, namedPipeName, onProgress, () =>
            {
                source.Dispose();
                response.Dispose();
            });
        }

        /// <summary>
        /// Creates a new named pipe from a Youtube video link.
        /// </summary>
        /// <param name="youtubeUri">Uri to Youtube video file.</param>
        /// <param name="fileExtension">Video-file extension.</param>
        /// <param name="namedPipeName">Named pipe.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <returns>Pipe name.</returns>
        public static string NamedPipeFromYoutubeUri(this Uri youtubeUri, out string fileExtension, string namedPipeName = "youtubeVideoPipe", Func<float, bool> onProgress = null)
        {
            if (youtubeUri.Host != "www.youtube.com")
                throw new ArgumentException("The provided URI is not valid Youtube URI.");

            var youtubeVideo = YouTube.Default.GetVideo(youtubeUri.AbsoluteUri); 
            fileExtension = youtubeVideo.FileExtension;

            VideoClient vc = new VideoClient();
            Stream source = vc.Stream(youtubeVideo);
            
            return NamedPipeFromStreamAsync(source, namedPipeName, onProgress, () =>
            {
                source.Dispose();
                vc.Dispose();
            });
        }

        /// <summary>
        /// Creates a new named pipe from a Youtube video link.
        /// </summary>
        /// <param name="youtubeUri">Uri to Youtube video file.</param>
        /// <param name="namedPipeName">Named pipe.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <returns>Pipe name.</returns>
        public static string NamedPipeFromYoutubeUri(this Uri youtubeUri, string namedPipeName = "youtubeVideoPipe", Func<float, bool> onProgress = null)
        {
            string fileExtension;
            return NamedPipeFromYoutubeUri(youtubeUri, out fileExtension, namedPipeName, onProgress);
        }

        /// <summary>
        /// Creates a new named pipe from a Youtube video link.
        /// </summary>
        /// <param name="source">Source stream.</param>
        /// <param name="namedPipeName">Named pipe.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <param name="onFinish">Action executed when a reading operation finishes.</param>
        /// <returns>Pipe name.</returns>
        public static string NamedPipeFromStreamAsync(this Stream source, string namedPipeName, Func<float, bool> onProgress = null, Action onFinish = null)
        {
            if (source == null)
                new ArgumentNullException(nameof(source));

            Task.Factory.StartNew(() =>
            {
                using (NamedPipeServerStream target = new NamedPipeServerStream(namedPipeName))
                {
                    target.WaitForConnection();
                    target.WaitForPipeDrain();

                    int bytes, copiedBytes = 0;
                    var buffer = new byte[1024];
                    while ((bytes = source.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        target.Write(buffer, 0, bytes);
                        copiedBytes += bytes;

                        if (onProgress != null)
                        {
                            bool shouldCancel = onProgress((float)copiedBytes / source.Length);
                            if (shouldCancel)
                                break;
                        }
                    }

                    target.Flush();
                    if (onFinish != null) onFinish();
                }
            });

            return namedPipeName;
        }

        #endregion

        #region Writing

        /// <summary>
        /// Copies the named pipe stream to the specified stream.
        /// </summary>
        /// <param name="pipeName">Pipe name.</param>
        /// <param name="target">Destination stream.</param>
        public static void CopyNamedPipeStream(this string pipeName, Stream target)
        {
            using (NamedPipeClientStream clientPipe = new NamedPipeClientStream(pipeName))
            {
                clientPipe.Connect();

                int bytes, copiedBytes = 0;
                var buffer = new byte[1024];
                while ((bytes = clientPipe.Read(buffer, 0, buffer.Length)) > 0)
                {
                    target.Write(buffer, 0, bytes);
                    copiedBytes += bytes;

                    /*if (onProgress != null)
                    {
                        bool shouldCancel = onProgress((float)copiedBytes / clientPipe.Length);
                        if (shouldCancel)
                            break;
                    }*/
                }

                target.Flush();
            }
        }

        /// <summary>
        /// Saves the named pipe stream to the specified file.
        /// </summary>
        /// <param name="pipeName">Pipe name.</param>
        /// <param name="targetFile">Destination file.</param>
        public static void SaveNamedPipeStream(this string pipeName, string targetFile)
        {
            using (Stream target = File.Create(targetFile))
            {
                CopyNamedPipeStream(pipeName, target);
            }
        }

        #endregion
    }
}


================================================
FILE: Source/IO.Web/WebImageExtensions.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.IO;
using System.Net;

namespace DotImaging
{
    /// <summary>
    /// Provides extensions for getting images from the Web.
    /// </summary>
    public static class WebImageExtensions
    {
        /// <summary>
        /// Gets the bytes from the Web using the specified uri.
        /// </summary>
        /// <param name="uri">File Web location.</param>
        /// <param name="onProgress">Function executed when progress changes. Return true to cancel the operation, false to continue.</param>
        /// <returns>Encoded image or undefined output in case if the operation is canceled.</returns>
        public static byte[] GetBytes(this Uri uri, Func<float, bool> onProgress = null)
        {
            byte[] output = null;
            var request = (HttpWebRequest)WebRequest.Create(uri.AbsoluteUri);

            using (WebResponse response = request.GetResponse())
            using (Stream source = response.GetResponseStream())
            using(MemoryStream target = new MemoryStream())
            {
                int bytes, copiedBytes = 0;
                var buffer = new byte[1024];
                while ((bytes = source.Read(buffer, 0, buffer.Length)) > 0)
                {
                    target.Write(buffer, 0, bytes);
                    copiedBytes += bytes;

                    if (onProgress != null)
                    {
                        bool shouldCancel = onProgress((float)copiedBytes / response.ContentLength);
                        if (shouldCancel)
                            break;
                    }
                }

                target.Flush();
                output = target.ToArray();
            }

            return output;
        }
    }
}


================================================
FILE: Source/Image/.nuSpec/readmeImage.txt
================================================
Provides .NET native array imaging extensions. Color-spaces and channel depth conversion is included.
Implements slim generic image class when fast pixel manipulation is needed.
To get compatibility for other image types install appropriate extension - NuGet package (e.g. Imaging.BitmapInterop).

1) Color and depth conversion:

	Bgr<byte>[,] image = ImageIO.LoadColor("sample.jpg"); //requires DotImaging.IO package
	Gray<float> grayFloatIm = image.ToGray()
	                               .Cast<float>();


2) Splitting and merging channels:

    Bgra<byte>[,] image = new Bgra<byte>[480, 640];
	Gray<byte>[][,] channels = image.SplitChannels(0, 1, 2); //take B, G and R channel
	Bgr<byte> bgrIm = channels.MergeChannels<Bgr<byte>, byte>();


3) Unsafe operations:

     Bgr<byte>[,] image = new Bgr<byte>[240, 320];

	 using(var unmanagedImage = image.Lock()) //create unmanaged structure that shares data with the array
	 {
		Bgr8* ptr = (Bgr8*)unmanagedImage.GetData(10, 10);
		ptr->B = 111;
	 }


4) OpenCV compatibility:

    Gray<byte>[,] image = new Gray<byte>[240, 320];

	IplImage iplIm = image.AsOpenCvImage(); //to OpenCV image
	Gray<byte>[,] imFromIpl = iplIm.AsImage().Clone(); //to array


5) LINQ:

	Bgr<byte>[,] image = ImageIO.LoadColor("sample.jpg").Clone();

	//get the modified blue channel 
	var modifiedImage = image.AsEnumerable()
	                         .Select(x => x.B / 2)
							 .ToArray2D(image.Size());


6) Misc

   Hsv<byte>[,] image = new Hsv<byte>[240, 320];
   image.SetValue(new Hsv<byte>(10, 10, 255)); //set pixels value

   Console.WriteLine(image.Size()); //write image size
   Console.WriteLine(image.ColorInfo()); //write color info
   ...


Discover more extensions as you type :)



================================================
FILE: Source/Image/ColorTypeConversions/ColorInfo.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;

namespace DotImaging
{
    /// <summary>
    /// Gets color information from color type and depth type.
    /// </summary>
    public class ColorInfo: IEquatable<ColorInfo>
    {
        static ConcurrentDictionary<Type, ColorInfo> colorInfos = new ConcurrentDictionary<Type, ColorInfo>();

        /// <summary>
        /// Color type (IColor).
        /// </summary>
        public Type ColorType { get; private set; }
        /// <summary>
        /// Number of channels that color has.
        /// </summary>
        public int ChannelCount { get; private set; }
        /// <summary>
        /// Number of bytes per channel.
        /// </summary>
        public int ChannelSize { get; private set; }
        /// <summary>
        /// Channel type. Only primitive types are supported.
        /// </summary>
        public Type ChannelType { get; private set; }
        /// <summary>
        /// Color size in bytes. Number of channels multiplied by channel size.
        /// </summary>
        public int Size { get { return this.ChannelSize * this.ChannelCount; } }

        /// <summary>
        /// Gets color info (depth is taken from color).
        /// </summary>
        /// <typeparam name="TColor">Member of <see cref="IColor"/></typeparam>
        /// <returns>Color info</returns>
        public static ColorInfo GetInfo<TColor>()
            //where TColor : IColor<T>
        {
            return GetInfo(typeof(TColor));
        }

        /// <summary>
        /// Gets color info (depth is taken from color).
        /// </summary>
        /// <param name="colorType">Color type. (member of IColor)</param>
        /// <returns>Color info</returns>
        public static ColorInfo GetInfo(Type colorType)
        {
            return colorInfos.GetOrAdd(colorType, getInfo);
        }

        private static ColorInfo getInfo(Type colorType)
        {
            ColorInfo ci = new ColorInfo();
            ci.ColorType = colorType;

            Type channelType;  int numberOfChannels;
            getChannelInfo(colorType, out channelType, out numberOfChannels);

            ci.ChannelCount = numberOfChannels;
            ci.ChannelType = channelType;
            ci.ChannelSize = Marshal.SizeOf(channelType);

            return ci;
        }

        private static void getChannelInfo(Type colorType, out Type channelType, out int numberOfChannels)
        {
            numberOfChannels = 0;

            var channelTypes = colorType
                               .GetFields(BindingFlags.Public | ~BindingFlags.Static) //if BindingFlags.Instance and if colorType is byte => zero length array
                               .Select(x => x.FieldType)
                               .ToArray();

            //ensure that all types are the same
            var _channelType = channelTypes[0];
            if (channelTypes.Where(x => x.Equals(_channelType)).Count() != channelTypes.Length)
                throw new Exception("Public fields must have the same type!");

            if (channelTypes.Length == 0)
                throw new Exception("Color structure must have at least one public field!");

            if (!_channelType.IsValueType)
                throw new Exception("Channel type must be a value type!");

            if (!_channelType.IsPrimitive)
                throw new Exception("Channel type must be a primitive type!");

            channelType = _channelType;
            numberOfChannels = channelTypes.Length;
        }

        /// <summary>
        /// Determines whether the object is equal compared to the specified object. 
        /// A default comparison is used. Please see overloads.
        /// </summary>
        /// <param name="other">Other object.</param>
        /// <returns>True if two objects are equal, false otherwise.</returns>
        public bool Equals(ColorInfo other)
        {
            return Equals(other, ComparableParts.Default);
        }

        /// <summary>
        /// Indicates what parts of color info should be compared.
        /// </summary>
        [Flags]
        public enum ComparableParts
        {
            /// <summary>
            /// Checks color depth type
            /// </summary>
            Depth = 0x1,
            /// <summary>
            /// Checks if one color can be casted to other (if colors are binary compatible).
            /// </summary>
            BinaryCompatible = 0x3, 
            /// <summary>
            /// Checks color type and depth type (if it is true all other properties are equal as well)
            /// </summary>
            Default =  0x4
        }

        /// <summary>
        /// Compares two color infos.
        /// </summary>
        /// <param name="other">Other color info.</param>
        /// <param name="cParts">Indicates what to compare. Default is: ComparableParts.Default. </param>
        /// <returns></returns>
        public bool Equals(ColorInfo other, ComparableParts cParts)
        {
            if(cParts == ComparableParts.Default)
            {
                return this.ColorType == other.ColorType && 
                       this.ChannelType == other.ChannelType;
            }

            if (cParts == ComparableParts.BinaryCompatible)
            {
                var castable = (this.ChannelCount == other.ChannelCount) && (this.ChannelType == other.ChannelType);
                return castable;
            }

            if (cParts == ComparableParts.Depth)
            { 
                var depth = this.ChannelType == other.ChannelType;
                return depth;
            }

            throw new Exception("Unknown comparison!");
        }

        /// <summary>
        /// Get string representation.
        /// </summary>
        /// <returns>String</returns>
        public override string ToString()
        {
            return String.Format("<{0}, {1}>", this.ColorType.Name, this.ChannelType.Name);
        }
    }

    /// <summary>
    /// Provides extensions for color to array conversion.
    /// </summary>
    public static class ColorToArrayExtensions
    {
        /// <summary>
        /// Converts color to array of type <typeparamref name="TDepth"/>.
        /// </summary>
        /// <typeparam name="TColor">Color type.</typeparam>
        /// <typeparam name="TDepth">Channel type.</typeparam>
        /// <param name="color">Color</param>
        /// <returns>Array whose length is the same as color's number of channels.</returns>
        public static TDepth[] ColorToArray<TColor, TDepth>(this TColor color)
            where TColor : IColor
            where TDepth : struct
        {
            var fields = typeof(TColor).GetFields(BindingFlags.Public | ~BindingFlags.Static);

            TDepth[] arr = new TDepth[fields.Length];

            for (int i = 0; i < fields.Length; i++)
            {
                var rawVal = fields[i].GetValue(color);
                arr[i] = (TDepth)Convert.ChangeType(rawVal, typeof(TDepth));
            }

            return arr;
        }
    }
}


================================================
FILE: Source/Image/ColorTypeConversions/ColorSpaces/Bgr.cs
================================================
#region Licence and Terms
// DotImaging Framework
// https://github.com/dajuric/dot-imaging
//
// Copyright © Darko Jurić, 2014-2019
// darko.juric2@gmail.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace DotImaging
{
      /// <summary>
    /// Represents Bgr color type of type <typeparam name="T">color depth</typeparam>.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct Bgr<T> : IColor3<T>
        where T : unmanaged
    {
        /// <summary>
        /// Creates new Bgr color.
        /// </summary>
        /// <param name="b">Blue</param>
        /// <param name="g">Green</param>
        /// <param name="r">Red</param>
        public Bgr(T b, T g, T r)
        {
            this.B = b;
            this.G = g;
            this.R = r;
        }

        /// <summary>
        /// Gets or sets the blue component.
        /// </summary>
        public T B;
        /// <summary>
        /// Gets or sets the green component.
        /// </summary>
        public T G;
        /// <summary>
        /// Gets or sets the red component.
        /// </summary>
  
Download .txt
gitextract_pvk6qki_/

├── .gitignore
├── Deploy/
│   ├── Licence.txt
│   ├── Logo/
│   │   └── DotImaging.pptx
│   └── Nuget/
│       └── Push.ps1
├── Directory.Build.props
├── DotImaging.sln
├── README.md
├── Samples/
│   ├── Sample.Basic/
│   │   ├── Program.cs
│   │   └── Sample.Basic.csproj
│   ├── Sample.Capture/
│   │   ├── Program.cs
│   │   └── Sample.Capture.csproj
│   ├── Sample.CaptureAndRecord/
│   │   ├── Program.cs
│   │   └── Sample.CaptureAndRecord.csproj
│   ├── Sample.ImageExtractor/
│   │   ├── Program.cs
│   │   └── Sample.ImageExtractor.csproj
│   ├── Sample.Interop/
│   │   ├── Program.cs
│   │   └── Sample.Interop.csproj
│   ├── Sample.MultipleCameraCapture/
│   │   ├── Program.cs
│   │   └── Sample.MultipleCameraCapture.csproj
│   ├── Sample.UI/
│   │   ├── Program.cs
│   │   └── Sample.UI.csproj
│   └── Sample.VideoStreaming/
│       ├── Program.cs
│       └── Sample.VideoStreaming.csproj
└── Source/
    ├── BitmapInterop/
    │   ├── .nuSpec/
    │   │   └── readmeImage.Bitmap.txt
    │   ├── BmpExtensions/
    │   │   ├── BitmapConversion.cs
    │   │   ├── BmpIO.cs
    │   │   └── ColorConversion.cs
    │   └── Image.BitmapInterop.csproj
    ├── IO/
    │   ├── .nuSpec/
    │   │   └── readmeIO.txt
    │   ├── Base/
    │   │   ├── Abstract/
    │   │   │   ├── ImageStream.cs
    │   │   │   ├── ImageStreamReader.cs
    │   │   │   └── ImageStreamWriter.cs
    │   │   └── CvInvoke.cs
    │   ├── IO.csproj
    │   ├── ImageIO.cs
    │   ├── Readers/
    │   │   ├── CameraCapture.cs
    │   │   ├── FileCapture.cs
    │   │   ├── ImageDirectoryCapture.cs
    │   │   └── VideoCaptureBase.cs
    │   ├── Utilities/
    │   │   ├── NaturalSortComparer.cs
    │   │   └── PathExtensions.cs
    │   ├── Writers/
    │   │   ├── ImageWriterExtension.cs
    │   │   └── VideoWriter.cs
    │   └── runtimes/
    │       └── ubuntu.16.04-x64/
    │           ├── libopencv_core.so.2.4
    │           ├── libopencv_highgui.so.2.4
    │           └── libopencv_video.so.2.4
    ├── IO.Web/
    │   ├── .nuSpec/
    │   │   └── readmeIO.Web.txt
    │   ├── IO.Web.csproj
    │   ├── NamedPipeExtensions.cs
    │   └── WebImageExtensions.cs
    ├── Image/
    │   ├── .nuSpec/
    │   │   └── readmeImage.txt
    │   ├── ColorTypeConversions/
    │   │   ├── ColorInfo.cs
    │   │   ├── ColorSpaces/
    │   │   │   ├── Bgr.cs
    │   │   │   ├── Bgra.cs
    │   │   │   ├── Gray.cs
    │   │   │   ├── Hsv.cs
    │   │   │   ├── IColor.cs
    │   │   │   └── Rgb.cs
    │   │   └── Converters/
    │   │       └── ColorConversionExtensions.cs
    │   ├── Extensions/
    │   │   ├── BasicExtensions.cs
    │   │   ├── ChannelMerger.cs
    │   │   ├── ChannelSplitter.cs
    │   │   ├── Convert.cs
    │   │   ├── Copy.cs
    │   │   ├── ImageFlipping.cs
    │   │   └── SpatialConvolution.cs
    │   ├── Image.csproj
    │   ├── Interop/
    │   │   ├── CvMat.cs
    │   │   └── IplImage.cs
    │   ├── Linq/
    │   │   └── ImagingLinq.cs
    │   ├── ParallelLauncher.cs
    │   ├── Slice2D.cs
    │   └── Unmanaged/
    │       ├── IImage.cs
    │       └── Image'1.cs
    ├── Primitives2D/
    │   ├── Box2D/
    │   │   └── Box2D.cs
    │   ├── Circle/
    │   │   ├── Circle.cs
    │   │   └── CircleF.cs
    │   ├── Ellipse/
    │   │   └── Ellipse.cs
    │   ├── Point/
    │   │   ├── Point'1.cs
    │   │   └── PointExtensions.cs
    │   ├── Primitives2D.csproj
    │   ├── Rectangle/
    │   │   └── RectangleExtensions.cs
    │   └── Size/
    │       └── SizeExtensions.cs
    └── UI.Image/
        ├── .nuSpec/
        │   └── readmeUI.Image.txt
        ├── Base/
        │   ├── CvCoreInvoke.cs
        │   └── CvInvoke.cs
        ├── Drawing.cs
        ├── ImageUI.cs
        ├── UI.Image.csproj
        └── runtimes/
            └── ubuntu.16.04-x64/
                ├── libopencv_core.so.2.4
                └── libopencv_highgui.so.2.4
Download .txt
SYMBOL INDEX (538 symbols across 60 files)

FILE: Samples/Sample.Basic/Program.cs
  class Program (line 8) | static class Program
    method Main (line 10) | static void Main()

FILE: Samples/Sample.Capture/Program.cs
  class Program (line 28) | class Program
    method Main (line 30) | [STAThread]
    method getResourceDir (line 60) | private static string getResourceDir()

FILE: Samples/Sample.CaptureAndRecord/Program.cs
  class Program (line 28) | static class Program
    method Main (line 30) | static void Main()
    method getResourceDir (line 62) | private static string getResourceDir()

FILE: Samples/Sample.ImageExtractor/Program.cs
  class Program (line 30) | class Program
    method Main (line 32) | static void Main(string[] args)
    method extractVideo (line 50) | private static void extractVideo(string fileName)
    method enumerateFiles (line 65) | private static IEnumerable<string> enumerateFiles(string fileMask)
    method getResourceDir (line 77) | private static string getResourceDir()
    method normalizePathDelimiters (line 82) | private static string normalizePathDelimiters(string path, string norm...

FILE: Samples/Sample.Interop/Program.cs
  class Program (line 28) | class Program
    method Main (line 30) | static void Main(string[] args)

FILE: Samples/Sample.MultipleCameraCapture/Program.cs
  class Program (line 29) | static class Program
    method Main (line 31) | static void Main()

FILE: Samples/Sample.UI/Program.cs
  class Program (line 31) | class Program
    method Main (line 33) | [STAThread]

FILE: Samples/Sample.VideoStreaming/Program.cs
  class Program (line 8) | class Program
    method Main (line 10) | public static void Main()

FILE: Source/BitmapInterop/BmpExtensions/BitmapConversion.cs
  class BitmapConversionExtensions (line 32) | public static class BitmapConversionExtensions
    method ToImage (line 52) | public static TColor[,] ToImage<TColor>(this Bitmap bmp)
    method toBitmap (line 79) | private static Bitmap toBitmap(IImage img, PixelFormat pixelFormat)
    method ToBitmap (line 97) | public static Bitmap ToBitmap(this Image<Gray<byte>> img)
    method ToBitmap (line 107) | public static Bitmap ToBitmap(this Image<Gray<short>> img)
    method ToBitmap (line 117) | public static Bitmap ToBitmap(this Image<Bgr<byte>> img)
    method ToBitmap (line 127) | public static Bitmap ToBitmap(this Image<Bgra<byte>> img)
    method ToBitmap (line 137) | public static Bitmap ToBitmap(this Image<Bgr<short>> img)
    method ToBitmap (line 147) | public static Bitmap ToBitmap(this Image<Bgra<short>> img)
    method ToBitmap (line 158) | public static Bitmap ToBitmap(this Gray<byte>[,] img)
    method ToBitmap (line 173) | public static Bitmap ToBitmap(this Gray<short>[,] img)
    method ToBitmap (line 188) | public static Bitmap ToBitmap(this Bgr<byte>[,] img)
    method ToBitmap (line 203) | public static Bitmap ToBitmap(this Bgra<byte>[,] img)
    method ToBitmap (line 218) | public static Bitmap ToBitmap(this Bgr<short>[,] img)
    method ToBitmap (line 233) | public static Bitmap ToBitmap(this Bgra<short>[,] img)
    method asBitmap (line 247) | private static Bitmap asBitmap(IImage img, PixelFormat pixelFormat)
    method AsBitmap (line 263) | public static Bitmap AsBitmap(this Image<Gray<byte>> img)
    method AsBitmap (line 274) | public static Bitmap AsBitmap(this Image<Gray<short>> img)
    method AsBitmap (line 285) | public static Bitmap AsBitmap(this Image<Bgr<byte>> img)
    method AsBitmap (line 296) | public static Bitmap AsBitmap(this Image<Bgra<byte>> img)
    method AsBitmap (line 307) | public static Bitmap AsBitmap(this Image<Bgr<short>> img)
    method AsBitmap (line 318) | public static Bitmap AsBitmap(this Image<Bgra<short>> img)
    method SetGrayscalePalette (line 331) | public static void SetGrayscalePalette(this Bitmap image)
    method LockBits (line 351) | public static BitmapData LockBits(this Bitmap bmp, ImageLockMode image...

FILE: Source/BitmapInterop/BmpExtensions/BmpIO.cs
  class BmpIO (line 31) | public static class BmpIO
    method BmpIO (line 35) | static BmpIO()
    method getEncoder (line 44) | private static ImageCodecInfo getEncoder(ImageFormat format)
    method Save (line 70) | public static void Save(this System.Drawing.Image image, Stream target...
    method Save (line 99) | public static void Save(this System.Drawing.Image image, string filena...

FILE: Source/BitmapInterop/BmpExtensions/ColorConversion.cs
  class ColorConversion (line 30) | public static class ColorConversion
    method ToColor (line 38) | public static System.Drawing.Color ToColor(this Gray<byte> color, byte...
    method ToColor (line 49) | public static System.Drawing.Color ToColor(this Bgr<byte> color, byte ...
    method ToColor (line 59) | public static System.Drawing.Color ToColor(this Bgra<byte> color)
    method ToBgr (line 69) | public static Bgr<byte> ToBgr(this System.Drawing.Color color)

FILE: Source/IO.Web/NamedPipeExtensions.cs
  class NamedPipeExtensions (line 34) | public static class NamedPipeExtensions
    method NamedPipeFromFileName (line 45) | public static string NamedPipeFromFileName(this string fileName, strin...
    method NamedPipeFromVideoUri (line 65) | public static string NamedPipeFromVideoUri(this Uri uri, string namedP...
    method NamedPipeFromYoutubeUri (line 86) | public static string NamedPipeFromYoutubeUri(this Uri youtubeUri, out ...
    method NamedPipeFromYoutubeUri (line 111) | public static string NamedPipeFromYoutubeUri(this Uri youtubeUri, stri...
    method NamedPipeFromStreamAsync (line 125) | public static string NamedPipeFromStreamAsync(this Stream source, stri...
    method CopyNamedPipeStream (line 169) | public static void CopyNamedPipeStream(this string pipeName, Stream ta...
    method SaveNamedPipeStream (line 199) | public static void SaveNamedPipeStream(this string pipeName, string ta...

FILE: Source/IO.Web/WebImageExtensions.cs
  class WebImageExtensions (line 31) | public static class WebImageExtensions
    method GetBytes (line 39) | public static byte[] GetBytes(this Uri uri, Func<float, bool> onProgre...

FILE: Source/IO/Base/Abstract/ImageStream.cs
  class ImageStream (line 31) | public abstract class ImageStream<TImage>: IDisposable
    method ImageStream (line 36) | protected ImageStream()
    method Seek (line 70) | public virtual long Seek(long offset, System.IO.SeekOrigin origin = Se...
    method Dispose (line 97) | public virtual void Dispose()
    method Open (line 105) | public abstract void Open();
    method Close (line 111) | public abstract void Close();

FILE: Source/IO/Base/Abstract/ImageStreamReader.cs
  class ImageStreamReader (line 34) | public abstract class ImageStreamReader: ImageStreamReader<IImage>
    method ImageStreamReader (line 47) | protected ImageStreamReader()
    method ReadAsync (line 65) | public Task<TImage> ReadAsync()
    method Read (line 84) | public TImage Read(out bool isExpired)
    method Read (line 98) | public TImage Read()
    method ReadInternal (line 110) | protected abstract bool ReadInternal(out TImage image);
    method GetEnumerator (line 119) | public IEnumerator<TImage> GetEnumerator()
    method GetEnumerator (line 129) | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnume...
  class ImageStreamReader (line 42) | public abstract class ImageStreamReader<TImage> : ImageStream<TImage>, I...
    method ImageStreamReader (line 47) | protected ImageStreamReader()
    method ReadAsync (line 65) | public Task<TImage> ReadAsync()
    method Read (line 84) | public TImage Read(out bool isExpired)
    method Read (line 98) | public TImage Read()
    method ReadInternal (line 110) | protected abstract bool ReadInternal(out TImage image);
    method GetEnumerator (line 119) | public IEnumerator<TImage> GetEnumerator()
    method GetEnumerator (line 129) | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnume...
  class ImageStreamReaderEnumerator (line 142) | public class ImageStreamReaderEnumerator<TImage> : IEnumerator<TImage>
    method ImageStreamReaderEnumerator (line 152) | public ImageStreamReaderEnumerator(ImageStreamReader<TImage> streamabl...
    method MoveNext (line 164) | public bool MoveNext()
    method Reset (line 173) | public void Reset()
    method Dispose (line 208) | public void Dispose()
  class ImageStreamReaderExtensions (line 221) | public static class ImageStreamReaderExtensions
    method ReadAs (line 229) | public static Image<TColor> ReadAs<TColor>(this ImageStreamReader<IIma...
    method ReadTo (line 249) | public static void ReadTo<TColor>(this ImageStreamReader<IImage> image...

FILE: Source/IO/Base/Abstract/ImageStreamWriter.cs
  class ImageStreamWriter (line 31) | public abstract class ImageStreamWriter : ImageStreamWriter<IImage>
    method ImageStreamWriter (line 44) | protected ImageStreamWriter()
    method WriteAsync (line 62) | public Task<bool> WriteAsync(TImage image)
    method Write (line 82) | public bool Write(TImage image)
    method WriteInternal (line 96) | protected abstract bool WriteInternal(TImage image);
  class ImageStreamWriter (line 39) | public abstract class ImageStreamWriter<TImage> : ImageStream<TImage>
    method ImageStreamWriter (line 44) | protected ImageStreamWriter()
    method WriteAsync (line 62) | public Task<bool> WriteAsync(TImage image)
    method Write (line 82) | public bool Write(TImage image)
    method WriteInternal (line 96) | protected abstract bool WriteInternal(TImage image);
  class ImageStreamWriterExtensions (line 102) | public static class ImageStreamWriterExtensions
    method Write (line 111) | public static bool Write<TColor>(this ImageStreamWriter<Image<TColor>>...

FILE: Source/IO/Base/CvInvoke.cs
  class VideoCodec (line 32) | public class VideoCodec
    method VideoCodec (line 58) | private VideoCodec(int codec)
    method FromName (line 71) | public static VideoCodec FromName(char c1, char c2, char c3, char c4)
    method FromName (line 82) | public static VideoCodec FromName(string codecName)
    method ToString (line 125) | public override string ToString()
  type CaptureProperty (line 141) | internal enum CaptureProperty: int
  type ImageLoadType (line 165) | [Flags]
  class CvInvoke (line 197) | internal static class CvInvoke
    method cvReleaseMat (line 205) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvReleaseImage (line 209) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvCreateCameraCapture (line 216) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvCreateFileCapture (line 219) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvReleaseCapture (line 224) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvGrabFrame (line 229) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvQueryFrame (line 233) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvGetCaptureProperty (line 238) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvSetCaptureProperty (line 242) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method GetImageSize (line 246) | public static Size GetImageSize(IntPtr capturePtr)
    method SetImageSize (line 255) | public static bool SetImageSize(IntPtr capturePtr, Size newSize)
    method cvCreateVideoWriter (line 278) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvWriteFrame (line 288) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvReleaseVideoWriter (line 297) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvLoadImage (line 304) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvSaveImage (line 308) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvEncodeImage (line 315) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvDecodeImageM (line 318) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...

FILE: Source/IO/ImageIO.cs
  class ImageIO (line 29) | public static class ImageIO
    method load (line 33) | private unsafe static IImage load(string fileName, ImageLoadType image...
    method LoadUnchanged (line 50) | public unsafe static IImage LoadUnchanged(this string fileName)
    method LoadColor (line 60) | public unsafe static Bgr<byte>[,] LoadColor(this string fileName)
    method LoadGray (line 74) | public unsafe static Gray<byte>[,] LoadGray(this string fileName)
    method TrySave (line 93) | public unsafe static bool TrySave(IImage image, string fileName)
    method Save (line 115) | private unsafe static void Save<TColor>(this Image<TColor> image, stri...
    method Save (line 128) | private unsafe static void Save<TColor>(this TColor[,] image, string f...
    method Save (line 145) | public static void Save(this Gray<byte>[,] image, string fileName)
    method Save (line 155) | public static void Save(this Gray<sbyte>[,] image, string fileName)
    method Save (line 165) | public static void Save(this Gray<short>[,] image, string fileName)
    method Save (line 175) | public static void Save(this Gray<ushort>[,] image, string fileName)
    method Save (line 185) | public static void Save(this Gray<int>[,] image, string fileName)
    method Save (line 195) | public static void Save(this Gray<float>[,] image, string fileName)
    method Save (line 205) | public static void Save(this Gray<double>[,] image, string fileName)
    method Save (line 219) | public static void Save(this Bgr<byte>[,] image, string fileName)
    method Save (line 229) | public static void Save(this Bgr<sbyte>[,] image, string fileName)
    method Save (line 239) | public static void Save(this Bgr<short>[,] image, string fileName)
    method Save (line 249) | public static void Save(this Bgr<ushort>[,] image, string fileName)
    method Save (line 259) | public static void Save(this Bgr<int>[,] image, string fileName)
    method Save (line 269) | public static void Save(this Bgr<float>[,] image, string fileName)
    method Save (line 279) | public static void Save(this Bgr<double>[,] image, string fileName)
    method Save (line 293) | public static void Save(this Bgra<byte>[,] image, string fileName)
    method Save (line 303) | public static void Save(this Bgra<sbyte>[,] image, string fileName)
    method Save (line 313) | public static void Save(this Bgra<short>[,] image, string fileName)
    method Save (line 323) | public static void Save(this Bgra<ushort>[,] image, string fileName)
    method Save (line 333) | public static void Save(this Bgra<int>[,] image, string fileName)
    method Save (line 343) | public static void Save(this Bgra<float>[,] image, string fileName)
    method Save (line 353) | public static void Save(this Bgra<double>[,] image, string fileName)
    method EncodeAsJpeg (line 370) | public static byte[] EncodeAsJpeg(this Gray<byte>[,] image, int jpegQu...
    method EncodeAsJpeg (line 381) | public static byte[] EncodeAsJpeg(this Bgr<byte>[,] image, int jpegQua...
    method EncodeAsJpeg (line 392) | public static byte[] EncodeAsJpeg(this Gray<ushort>[,] image, int jpeg...
    method EncodeAsJpeg (line 403) | public static byte[] EncodeAsJpeg(this Bgr<ushort>[,] image, int jpegQ...
    method EncodeAsPng (line 414) | public static byte[] EncodeAsPng(this Gray<byte>[,] image, int pngComp...
    method EncodeAsPng (line 425) | public static byte[] EncodeAsPng(this Bgr<byte>[,] image, int pngCompr...
    method EncodeAsPng (line 436) | public static byte[] EncodeAsPng(this Bgra<byte>[,] image, int pngComp...
    method EncodeAsPng (line 447) | public static byte[] EncodeAsPng(this Gray<ushort>[,] image, int pngCo...
    method EncodeAsPng (line 458) | public static byte[] EncodeAsPng(this Bgr<ushort>[,] image, int pngCom...
    method EncodeAsPng (line 469) | public static byte[] EncodeAsPng(this Bgra<ushort>[,] image, int pngCo...
    method Encode (line 480) | public static byte[] Encode(this Gray<byte>[,] image, string extension)
    method Encode (line 491) | public static byte[] Encode(this Bgr<byte>[,] image, string extension)
    method Encode (line 502) | public static byte[] Encode(this Bgra<byte>[,] image, string extension)
    method Encode (line 513) | public static byte[] Encode(this Gray<ushort>[,] image, string extension)
    method Encode (line 524) | public static byte[] Encode(this Bgr<ushort>[,] image, string extension)
    method Encode (line 535) | public static byte[] Encode(this Bgra<ushort>[,] image, string extension)
    method encodeAsJpeg (line 540) | static byte[] encodeAsJpeg<TColor>(TColor[,] image, int jpegQuality = 95)
    method encodeAsPng (line 550) | static byte[] encodeAsPng<TColor>(TColor[,] image, int pngCompression ...
    method encode (line 560) | static unsafe byte[] encode<TColor>(TColor[,] image, string extension,...
    method DecodeAsColorImage (line 593) | public unsafe static Bgr<byte>[,] DecodeAsColorImage(this byte[] encod...
    method DecodeAsGrayImage (line 603) | public unsafe static Gray<byte>[,] DecodeAsGrayImage(this byte[] encod...
    method decodeImage (line 608) | unsafe static TColor[,] decodeImage<TColor>(byte[] encodedImage, Image...

FILE: Source/IO/Readers/CameraCapture.cs
  class CameraCapture (line 30) | public class CameraCapture: VideoCaptureBase
    method CameraCapture (line 38) | public CameraCapture(int cameraIdx = 0)
    method Open (line 49) | public override void Open()

FILE: Source/IO/Readers/FileCapture.cs
  class FileCapture (line 31) | public class FileCapture: VideoCaptureBase
    method FileCapture (line 45) | public FileCapture(string sourceName)
    method Open (line 78) | public override void Open()
    method Seek (line 104) | public override long Seek(long offset, System.IO.SeekOrigin origin = S...

FILE: Source/IO/Readers/ImageDirectoryCapture.cs
  class ImageDirectoryCapture (line 32) | public class ImageDirectoryCapture : ImageStreamReader
    method ImageDirectoryCapture (line 46) | public ImageDirectoryCapture(string dirPath, string searchPattern, boo...
    method ImageDirectoryCapture (line 58) | public ImageDirectoryCapture(string dirPath, string[] searchPatterns, ...
    method Open (line 91) | public override void Open() { }
    method Close (line 96) | public override void Close()
    method ReadInternal (line 107) | protected override bool ReadInternal(out IImage image)
    method Seek (line 139) | public override long Seek(long offset, SeekOrigin origin = SeekOrigin....

FILE: Source/IO/Readers/VideoCaptureBase.cs
  class VideoCaptureBase (line 30) | public abstract class VideoCaptureBase : ImageStreamReader
    method Close (line 40) | public override void Close()
    method ReadInternal (line 52) | protected override bool ReadInternal(out IImage image)

FILE: Source/IO/Utilities/NaturalSortComparer.cs
  class NaturalSortComparer (line 32) | class NaturalSortComparer: IComparer<string>
    method NaturalSortComparer (line 40) | public NaturalSortComparer(bool inAscendingOrder = true)
    method Compare (line 53) | public int Compare(string x, string y)
    method Compare (line 62) | int IComparer<string>.Compare(string x, string y)
    method PartCompare (line 108) | private static int PartCompare(string left, string right)

FILE: Source/IO/Utilities/PathExtensions.cs
  class PathExtensions (line 32) | static class PathExtensions
    method EnumerateFiles (line 45) | public static IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo ...

FILE: Source/IO/Writers/ImageWriterExtension.cs
  class ImageWriterExtension (line 31) | public static class ImageWriterExtension
    method SaveFrames (line 40) | public static void SaveFrames(this ImageStreamReader imageSource, stri...

FILE: Source/IO/Writers/VideoWriter.cs
  class VideoWriter (line 30) | public class VideoWriter : ImageStreamWriter
    method VideoWriter (line 67) | public VideoWriter(string fileName, Size frameSize, float fps = 30, bo...
    method VideoWriter (line 79) | public VideoWriter(string fileName, Size frameSize, float fps, bool is...
    method Open (line 96) | public override void Open()
    method WriteInternal (line 128) | protected unsafe override bool WriteInternal(IImage image)
    method Close (line 161) | public override void Close()

FILE: Source/Image/ColorTypeConversions/ColorInfo.cs
  class ColorInfo (line 33) | public class ColorInfo: IEquatable<ColorInfo>
    method GetInfo (line 63) | public static ColorInfo GetInfo<TColor>()
    method GetInfo (line 74) | public static ColorInfo GetInfo(Type colorType)
    method getInfo (line 79) | private static ColorInfo getInfo(Type colorType)
    method getChannelInfo (line 94) | private static void getChannelInfo(Type colorType, out Type channelTyp...
    method Equals (line 127) | public bool Equals(ColorInfo other)
    type ComparableParts (line 135) | [Flags]
    method Equals (line 158) | public bool Equals(ColorInfo other, ComparableParts cParts)
    method ToString (line 185) | public override string ToString()
  class ColorToArrayExtensions (line 194) | public static class ColorToArrayExtensions
    method ColorToArray (line 203) | public static TDepth[] ColorToArray<TColor, TDepth>(this TColor color)

FILE: Source/Image/ColorTypeConversions/ColorSpaces/Bgr.cs
  type Bgr (line 31) | [StructLayout(LayoutKind.Sequential)]
    method Bgr (line 41) | public Bgr(T b, T g, T r)
    method ToString (line 65) | public override string ToString()
    method Convert (line 109) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method Convert (line 126) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method Convert (line 141) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method Convert (line 155) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
  class BgrColorConversionExtensions (line 203) | public static class BgrColorConversionExtensions
    method ToGray (line 210) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method ToHsv (line 223) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
  type Bgr8 (line 236) | public struct Bgr8

FILE: Source/Image/ColorTypeConversions/ColorSpaces/Bgra.cs
  type Bgra (line 29) | [StructLayout(LayoutKind.Sequential)]
    method Bgra (line 40) | public Bgra(T b, T g, T r, T a)
    method ToString (line 69) | public override string ToString()
    method Convert (line 96) | public static void Convert(Bgra<byte> bgra, ref Bgr<byte> bgr)
    method Convert (line 108) | public static void Convert(Bgra<byte> bgra, ref Gray<byte> gray)
  type Bgra8 (line 120) | public struct Bgra8

FILE: Source/Image/ColorTypeConversions/ColorSpaces/Gray.cs
  type Gray (line 29) | [StructLayout(LayoutKind.Sequential)]
    method Gray (line 37) | public Gray(T intensity)
    method ToString (line 71) | public override string ToString()
    method Convert (line 81) | public static void Convert(Gray<T> gray, ref Bgr<T> bgr)
    method Convert (line 93) | public static void Convert(Gray<byte> gray, ref Bgra<byte> bgra)

FILE: Source/Image/ColorTypeConversions/ColorSpaces/Hsv.cs
  type Hsv (line 30) | [StructLayout(LayoutKind.Sequential)]
    method Hsv (line 40) | public Hsv(T hue, T saturation, T value)
    method ToString (line 64) | public override string ToString()
    method Convert (line 87) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
  class HsvColorConversionExtensions (line 135) | public static class HsvColorConversionExtensions
    method ToBgr (line 142) | [MethodImpl(MethodImplOptions.AggressiveInlining)]

FILE: Source/Image/ColorTypeConversions/ColorSpaces/IColor.cs
  type IColor (line 27) | public interface IColor { }
  type IColor (line 33) | public interface IColor<T> : IColor
  type IColor2 (line 40) | public interface IColor2 : IColor { }
  type IColor2 (line 45) | public interface IColor2<T> : IColor2, IColor<T>
  type IColor3 (line 52) | public interface IColor3 : IColor { }
  type IColor3 (line 58) | public interface IColor3<T> : IColor3, IColor<T>
  type IColor4 (line 65) | public interface IColor4 : IColor { }
  type IColor4 (line 71) | public interface IColor4<T> : IColor4, IColor<T>

FILE: Source/Image/ColorTypeConversions/ColorSpaces/Rgb.cs
  type Rgb (line 31) | [StructLayout(LayoutKind.Sequential)]
    method Rgb (line 41) | public Rgb(T r, T g, T b)
    method ToString (line 65) | public override string ToString()
    method Convert (line 88) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
  type Rgb8 (line 101) | public struct Rgb8

FILE: Source/Image/ColorTypeConversions/Converters/ColorConversionExtensions.cs
  class ColorConversionExtensions (line 30) | public static class ColorConversionExtensions
    method ToBgr (line 39) | public static Bgr<byte>[,] ToBgr(this Gray<byte>[,] grayIm)
    method ToBgr (line 50) | public static Bgr<byte>[,] ToBgr(this Gray<byte>[,] grayIm, Rectangle ...
    method ToBgra (line 60) | public static Bgra<byte>[,] ToBgra(this Gray<byte>[,] grayIm)
    method ToBgra (line 71) | public static Bgra<byte>[,] ToBgra(this Gray<byte>[,] grayIm, Rectangl...
    method ToBgra (line 85) | public static Bgra<byte>[,] ToBgra(this Bgr<byte>[,] image)
    method ToBgra (line 96) | public static Bgra<byte>[,] ToBgra(this Bgr<byte>[,] image, Rectangle ...
    method ToGray (line 106) | public static Gray<byte>[,] ToGray(this Bgr<byte>[,] image)
    method ToGray (line 117) | public static Gray<byte>[,] ToGray(this Bgr<byte>[,] image, Rectangle ...
    method ToHsv (line 127) | public static Hsv<byte>[,] ToHsv(this Bgr<byte>[,] image)
    method ToHsv (line 138) | public static Hsv<byte>[,] ToHsv(this Bgr<byte>[,] image, Rectangle area)
    method ToBgr (line 152) | public static Bgr<byte>[,] ToBgr(this Rgb<byte>[,] image)
    method ToBgr (line 163) | public static Bgr<byte>[,] ToBgr(this Rgb<byte>[,] image, Rectangle area)
    method ToBgr (line 177) | public static Bgr<byte>[,] ToBgr(this Bgra<byte>[,] image)
    method ToBgr (line 188) | public static Bgr<byte>[,] ToBgr(this Bgra<byte>[,] image, Rectangle a...
    method ToGray (line 198) | public static Gray<byte>[,] ToGray(this Bgra<byte>[,] image)
    method ToGray (line 209) | public static Gray<byte>[,] ToGray(this Bgra<byte>[,] image, Rectangle...
    method ToBgr (line 222) | public static Bgr<byte>[,] ToBgr(this Hsv<byte>[,] image)
    method ToGray (line 233) | public static Bgr<byte>[,] ToGray(this Hsv<byte>[,] image, Rectangle a...
    method ToBgr (line 249) | public static Bgr<byte>[,] ToBgr(this IImage image)
    method ToBgra (line 274) | public static Bgra<byte>[,] ToBgra(this IImage image)
    method ToGray (line 299) | public static Gray<byte>[,] ToGray(this IImage image)
    method ToBgr (line 325) | public static Bgr<byte>[,] ToBgr(this Array array2D)
    method ToBgra (line 351) | public static Bgra<byte>[,] ToBgra(this Array array2D)
    method ToGray (line 377) | public static Gray<byte>[,] ToGray(this Array array2D)

FILE: Source/Image/Extensions/BasicExtensions.cs
  class ArrayImageBasicExtensions (line 30) | public static class ArrayImageBasicExtensions
    method Width (line 38) | public static int Width<T>(this T[,] image)
    method Height (line 49) | public static int Height<T>(this T[,] image)
    method Size (line 60) | public static Size Size<T>(this T[,] image)
    method Lock (line 71) | public static Image<TColor> Lock<TColor>(this TColor[,] array)
    method Lock (line 84) | public static Image<TColor> Lock<TColor>(this TColor[,] array, Rectang...
    method Clear (line 95) | public static void Clear<T>(this T[,] array)
    method Clone (line 107) | public static T[,] Clone<T>(this T[,] array)
    method CopyBlank (line 119) | public static T[,] CopyBlank<T>(this T[,] array)
    method ColorInfo (line 130) | public static ColorInfo ColorInfo<TColor>(this TColor[,] source)
    method CalculateStride (line 142) | public static int CalculateStride<TImage>(this TImage image, int allig...
    method Convert (line 164) | public static TDst[,] Convert<TSrc, TDst>(this TSrc[,] source, Func<TS...
    method Apply (line 189) | public static T[,] Apply<T>(this T[,] source, Func<T, T> apply, bool i...
    method SetValue (line 211) | public static void SetValue<T>(this T[,] array, T value)
    method SetValue (line 228) | public static void SetValue<T>(this T[,] array, T value, Rectangle area)
    method SetValue (line 246) | public static void SetValue<T>(this T[,] array, T value, Rectangle are...
    method SetValue (line 267) | public static void SetValue<T>(this T[,] array, T value, Rectangle are...
    method SetValue (line 287) | public static void SetValue<T>(this T[,] array, T value, Gray<byte>[,]...
    method SetValue (line 307) | public static void SetValue<T>(this T[,] array, T value, bool[,] mask)

FILE: Source/Image/Extensions/ChannelMerger.cs
  class ChannelMerger (line 30) | public static class ChannelMerger
    method MergeChannels (line 40) | public static TSrcColor[,] MergeChannels<TSrcColor, TDepth>(this IList...
    method MergeChannels (line 57) | public static TSrcColor[,] MergeChannels<TSrcColor, TDepth>(this IList...
    method ReplaceChannel (line 84) | public static void ReplaceChannel<TSrcColor, TDepth>(this TSrcColor[,]...
    method replaceChannel (line 95) | private static unsafe void replaceChannel<TSrcColor, TDepth>(Image<TSr...

FILE: Source/Image/Extensions/ChannelSplitter.cs
  class ChannelSplitter (line 30) | public static class ChannelSplitter
    method SplitChannels (line 40) | public static unsafe Gray<TDepth>[][,] SplitChannels<TSrcColor, TDepth...
    method SplitChannels (line 57) | public static unsafe Gray<TDepth>[][,] SplitChannels<TSrcColor, TDepth...
    method GetChannel (line 83) | public static unsafe Gray<TDepth>[,] GetChannel<TSrcColor, TDepth>(thi...
    method GetChannel (line 100) | public static unsafe Gray<TDepth>[,] GetChannel<TSrcColor, TDepth>(thi...

FILE: Source/Image/Extensions/Convert.cs
  class ConvertExtensions (line 40) | public static class ConvertExtensions
    method Convert (line 50) | public static TDst[,] Convert<TSrc, TDst>(this TSrc[,] source, Convert...
    method Convert (line 66) | public static TDst[,] Convert<TSrc, TDst>(this TSrc[,] source, Convert...

FILE: Source/Image/Extensions/Copy.cs
  class Copy (line 31) | public static class Copy
    method memcpy (line 33) | [DllImport("ntdll.dll", CallingConvention = CallingConvention.Cdecl)]
    method Copy (line 36) | static Copy()
    method unsafeCopy_ElementByElement (line 74) | static unsafe void unsafeCopy_ElementByElement(IntPtr src, IntPtr dst,...
    method UnsafeCopy2D (line 105) | public unsafe static void UnsafeCopy2D(IntPtr srcPtr, IntPtr destPtr, ...
    method UnsafeCopy2D (line 132) | public unsafe static void UnsafeCopy2D(IntPtr srcPtr, IntPtr destPtr, ...
    method Clone (line 144) | public static T[,] Clone<T>(this T[,] array, Rectangle area)
    method Clone (line 166) | public static T[,] Clone<T>(this Image<T> image)
    method CopyTo (line 187) | public static void CopyTo<T>(this Image<T> source, Image<T> destination)
    method CopyTo (line 203) | public static void CopyTo<T>(this Image<T> source, T[,] destination)
    method CopyTo (line 222) | public static void CopyTo<T>(this T[,] source, T[,] destination, Point...
    method CopyToOrCreate (line 241) | public static void CopyToOrCreate<TColor>(this Image<TColor> source, r...
    method CopyTo (line 268) | public static void CopyTo<TColor>(this TColor[,] source, TColor[,] des...
    method CopySelective (line 291) | public static void CopySelective<T>(this T[,] source, Rectangle source...

FILE: Source/Image/Extensions/ImageFlipping.cs
  type FlipDirection (line 31) | [Flags]
  class ImageFlipping (line 55) | public static class ImageFlipping
    method FlipImage (line 64) | public static TColor[,] FlipImage<TColor>(this TColor[,] source, FlipD...
    method FlipImage (line 84) | public static void FlipImage<TColor>(this TColor[,] source, Rectangle ...

FILE: Source/Image/Extensions/SpatialConvolution.cs
  class SpatialConvolution (line 29) | public static class SpatialConvolution
    method convolve (line 48) | private unsafe static void convolve(KernelThread thread, float* source...
    method ConvolveUnsafe (line 89) | public unsafe static void ConvolveUnsafe(float* source, int sourceWidt...
    method Convolve (line 109) | public unsafe static float[,] Convolve(this float[,] source, float[,] ...
    method Convolve (line 129) | public unsafe static float[,] Convolve(this float[,] source, float[,] ...
    method Convolve (line 142) | public unsafe static TColor[,] Convolve<TColor>(this TColor[,] source,...

FILE: Source/Image/Interop/CvMat.cs
  type CvMat (line 31) | [StructLayout(LayoutKind.Sequential)]
    type CvChannelDepth (line 37) | public enum CvChannelDepth : int
    method FromUserData (line 111) | public static CvMat FromUserData(IntPtr imageData, int width, int heig...
    method getDepth (line 163) | static int getDepth(int flags)
  class CvMatTypeConversions (line 175) | public static class CvMatTypeConversions
    method CvMatTypeConversions (line 179) | static CvMatTypeConversions()
    method AsCvMat (line 200) | public static CvMat AsCvMat(this IImage image)
    method ToArray (line 213) | public static TColor[,] ToArray<TColor>(this CvMat cvMat)

FILE: Source/Image/Interop/IplImage.cs
  type IplImage (line 31) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    type IplChannelDepth (line 42) | public enum IplChannelDepth : uint
    type ChannelDataOrder (line 81) | public enum ChannelDataOrder : int
    type DataOrigin (line 96) | public enum DataOrigin : int
    method IplImage (line 199) | internal IplImage(IImage image, Func<Type, IplChannelDepth> translatio...
    method FromPointer (line 237) | public static IplImage FromPointer(IntPtr pointerToStructure)
  class ImageOpenCVImageConversions (line 249) | public static class ImageOpenCVImageConversions
    class IplColorInfo (line 251) | class IplColorInfo: IEquatable<IplColorInfo>
      method IplColorInfo (line 253) | public IplColorInfo(int channelCount, IplImage.IplChannelDepth chann...
      method Equals (line 262) | public bool Equals(IplColorInfo other)
      method GetHashCode (line 271) | public override int GetHashCode()
    class GenericImageConstructor (line 277) | class GenericImageConstructor
      method Create (line 279) | public static GenericImageConstructor Create<TColor>()
      method GenericImageConstructor (line 300) | private GenericImageConstructor()
    method ImageOpenCVImageConversions (line 307) | static ImageOpenCVImageConversions()
    method AsCvIplImage (line 379) | public static IplImage AsCvIplImage(this IImage image)
    method AsImage (line 402) | public static unsafe IImage AsImage(this IplImage iplImage, Action<obj...

FILE: Source/Image/Linq/ImagingLinq.cs
  class ImageLinqExtensions (line 32) | public static partial class ImageLinqExtensions
    method ToArray2D (line 42) | public static T[,] ToArray2D<T>(this IEnumerable<T> collection, Size s...
    method ToArray2D (line 56) | public static T[,] ToArray2D<T>(this IEnumerable<T> collection, int wi...
    method SliceUniform (line 82) | public static IEnumerable<Slice2D<T>> SliceUniform<T>(this T[,] array)
    method AsParallelOrdered (line 109) | public static ParallelQuery<T> AsParallelOrdered<T>(this T[,] array) /...
    method Row (line 122) | public static IEnumerable<T> Row<T>(this T[,] array, int row)
    method Column (line 139) | public static IEnumerable<T> Column<T>(this T[,] array, int column)
    method AsEnumerable (line 157) | public static IEnumerable<T> AsEnumerable<T>(this T[,] array, Rectangl...
    method AsEnumerable (line 175) | public static IEnumerable<T> AsEnumerable<T>(this T[,] array)
    method EnumerateWith (line 193) | public static IEnumerable<TOutput> EnumerateWith<TFirst, TSecond, TOut...
    method EnumerateWith (line 222) | public static IEnumerable<TOutput> EnumerateWith<TFirst, TSecond, TOut...

FILE: Source/Image/ParallelLauncher.cs
  type KernelThread (line 30) | public struct KernelThread
  class ParallelLauncher (line 45) | public static class ParallelLauncher
    method Launch (line 55) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method Launch (line 71) | [MethodImpl(MethodImplOptions.AggressiveInlining)]

FILE: Source/Image/Slice2D.cs
  class Slice2D (line 30) | public class Slice2D<T>
    method Slice2D (line 36) | public Slice2D(T[,] array)
    method Slice2D (line 47) | public Slice2D(T[,] array, Rectangle area)
    method Equals (line 90) | public override bool Equals(object other)
    method GetHashCode (line 106) | public override int GetHashCode()
  class Slice2DExtensions (line 115) | public static class Slice2DExtensions
    method Clone (line 123) | public static unsafe T[,] Clone<T>(this Slice2D<T> slice)

FILE: Source/Image/Unmanaged/IImage.cs
  type IImage (line 30) | public interface IImage: IDisposable, IEquatable<IImage>
    method GetData (line 62) | IntPtr GetData(int row, int col);
    method GetData (line 68) | IntPtr GetData(int row);
    method GetSubRect (line 74) | IImage GetSubRect(Rectangle rect);

FILE: Source/Image/Unmanaged/Image'1.cs
  class Image (line 34) | public class Image<TColor> : IImage, IEquatable<IImage>, IDisposable
    method Image (line 42) | private Image()
    method Lock (line 53) | public static Image<TColor> Lock(TColor[,] array)
    method Lock (line 75) | public static Image<TColor> Lock(byte[] rawImageArray, int width)
    method Image (line 98) | public Image(IntPtr imageData, int width, int height, int stride, obje...
    method initializeProperties (line 106) | private static void initializeProperties(Image<TColor> im, IntPtr imag...
    method GetData (line 153) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method GetData (line 167) | [MethodImpl(MethodImplOptions.AggressiveInlining)]
    method GetSubRect (line 181) | public Image<TColor> GetSubRect(Rectangle rect)
    method GetSubRect (line 197) | IImage IImage.GetSubRect(Rectangle rect)
    method Equals (line 212) | public bool Equals(IImage other)
    method Equals (line 229) | public override bool Equals(object obj)
    method GetHashCode (line 238) | public override int GetHashCode()
    method Dispose (line 253) | public void Dispose()

FILE: Source/Primitives2D/Box2D/Box2D.cs
  type Box2D (line 32) | [StructLayout(LayoutKind.Sequential)]
    method Box2D (line 58) | public Box2D(RectangleF rect, float angle)
    method Box2D (line 68) | public Box2D(PointF center, SizeF size, float angle)
    method GetMinArea (line 86) | public RectangleF GetMinArea()
    method GetVertices (line 103) | public PointF[] GetVertices()
    method getNonRotatedVertices (line 117) | private PointF[] getNonRotatedVertices()
    method Equals (line 156) | public override bool Equals(object obj)
    method GetHashCode (line 168) | public override int GetHashCode()

FILE: Source/Primitives2D/Circle/Circle.cs
  type Circle (line 54) | public struct Circle
    method Circle (line 87) | public Circle(Point position, int radius)
    method Circle (line 97) | public Circle(int x, int y, int radius)
    method DistanceToPoint (line 139) | public double DistanceToPoint(Point point)

FILE: Source/Primitives2D/Circle/CircleF.cs
  type CircleF (line 55) | public struct CircleF
    method CircleF (line 88) | public CircleF(PointF position, float radius)
    method CircleF (line 98) | public CircleF(float x, float y, float radius)
    method CircleF (line 140) | public CircleF(PointF p1, PointF p2, PointF p3)
    method DistanceToPoint (line 169) | public double DistanceToPoint(PointF point)

FILE: Source/Primitives2D/Ellipse/Ellipse.cs
  type Ellipse (line 31) | [StructLayout(LayoutKind.Sequential)]
    method Ellipse (line 40) | public Ellipse(PointF center, SizeF size, float angle = 0)
    method Fit (line 86) | public static Ellipse Fit(double[,] covMatrix, PointF center = default...
    method Fit (line 103) | public static Ellipse Fit(double a, double b, double c, PointF center,...
    method Fit (line 138) | public static Ellipse Fit(double a, double b, double c, PointF center ...

FILE: Source/Primitives2D/Point/Point'1.cs
  type Point (line 28) | public struct Point<T>
    method Point (line 36) | public Point(T x, T y)
    method Equals (line 57) | public override bool Equals(object obj)
    method GetHashCode (line 70) | public override int GetHashCode()
    method ToString (line 79) | public override string ToString()

FILE: Source/Primitives2D/Point/PointExtensions.cs
  class Point32iExtensions (line 32) | public static class Point32iExtensions
    method UpScale (line 41) | public static PointF UpScale(this Point p, int levels = 1, double fact...
    method DownScale (line 59) | public static PointF DownScale(this Point p, int levels = 1, double fa...
    method Add (line 76) | public static Point Add(this Point point, Point offset)
    method Subtract (line 91) | public static Point Subtract(this Point point, Point offset)
    method DistanceTo (line 106) | public static double DistanceTo(this Point pointA, Point pointB)
    method Rotate (line 119) | public static PointF Rotate(this Point pointToRotate, double angleDeg,...
    method Rotate (line 146) | public static PointF Rotate(this Point pointToRotate, double angleDeg)
    method Negate (line 156) | public static Point Negate(this Point point)
  class Point32fExtensions (line 169) | public static class Point32fExtensions
    method UpScale (line 178) | public static PointF UpScale(this PointF p, int levels = 1, double fac...
    method DownScale (line 196) | public static PointF DownScale(this PointF p, int levels = 1, double f...
    method Add (line 213) | public static PointF Add(this PointF point, PointF offset)
    method Subtract (line 228) | public static PointF Subtract(this PointF point, PointF offset)
    method DistanceTo (line 243) | public static double DistanceTo(this PointF pointA, PointF pointB)
    method Rotate (line 256) | public static PointF Rotate(this PointF pointToRotate, double angleDeg...
    method Rotate (line 283) | public static PointF Rotate(this PointF pointToRotate, double angleDeg)
    method Round (line 293) | public static Point Round(this PointF point)
    method Floor (line 303) | public static Point Floor(this PointF p)
    method Negate (line 317) | public static PointF Negate(this PointF point)
  class Point32fCollectionExtensions (line 330) | public static class Point32fCollectionExtensions
    method IsInPolygon (line 340) | public static bool IsInPolygon(this IList<PointF> poly, float x, float y)
    method BoundingRect (line 388) | public static RectangleF BoundingRect(this IEnumerable<PointF> points)
    method Center (line 416) | public static PointF Center(this IEnumerable<PointF> points)
    method IsRectangle (line 439) | public static bool IsRectangle(this IEnumerable<PointF> points)
  class Point32iCollectionExtensions (line 476) | public static class Point32iCollectionExtensions
    method IsInPolygon (line 486) | public static bool IsInPolygon(this IList<Point> poly, float x, float y)
    method BoundingRect (line 534) | public static Rectangle BoundingRect(this IEnumerable<Point> points)
    method Center (line 562) | public static PointF Center(this IEnumerable<Point> points)
    method IsRectangle (line 585) | public static bool IsRectangle(this IEnumerable<Point> points)

FILE: Source/Primitives2D/Rectangle/RectangleExtensions.cs
  class RectangleExtennsions (line 31) | public static class RectangleExtennsions
    method IntersectionPercent (line 39) | public static float IntersectionPercent(this Rectangle rect1, Rectangl...
    method Area (line 49) | public static int Area(this Rectangle rect)
    method Center (line 59) | public static Point Center(this Rectangle rect)
    method Vertices (line 69) | public static Point[] Vertices(this Rectangle rect)
    method IsEmptyArea (line 85) | public static bool IsEmptyArea(this Rectangle rect)
    method BoundingRectangle (line 95) | public static Rectangle BoundingRectangle(this IEnumerable<Rectangle> ...
  class RectangleFExtensions (line 115) | public static class RectangleFExtensions
    method IntersectionPercent (line 123) | public static float IntersectionPercent(this RectangleF rect1, Rectang...
    method Area (line 141) | public static float Area(this RectangleF rect)
    method Center (line 151) | public static PointF Center(this RectangleF rect)
    method Vertices (line 161) | public static PointF[] Vertices(this RectangleF rect)
    method IsEmptyArea (line 177) | public static bool IsEmptyArea(this RectangleF rect)
    method BoundingRectangle (line 187) | public static RectangleF BoundingRectangle(this IEnumerable<RectangleF...

FILE: Source/Primitives2D/Size/SizeExtensions.cs
  class SizeExtensions (line 30) | public static class SizeExtensions
    method Area (line 37) | public static int Area(this Size size)
    method ToRectangle (line 47) | public static Rectangle ToRectangle(this Size size)
    method Scale (line 58) | public static Size Scale(this Size size, float scale)
  class SizeFExtensions (line 69) | public static class SizeFExtensions
    method Area (line 76) | public static float Area(this SizeF size)
    method ToRectangleF (line 86) | public static RectangleF ToRectangleF(this SizeF size)
    method Scale (line 97) | public static Size Scale(this Size size, float scale)

FILE: Source/UI.Image/Base/CvCoreInvoke.cs
  type FontTypes (line 32) | public enum FontTypes
  type Font (line 71) | [StructLayout(LayoutKind.Sequential)]
    method Font (line 131) | public Font(FontTypes type, double hscale, double vscale, int thicknes...
    method GetTextSize (line 143) | public Size GetTextSize(string text, int baseline)
  type CvScalar (line 167) | internal struct CvScalar
  type LineTypes (line 190) | internal enum LineTypes
  class CvCoreInvoke (line 209) | internal static class CvCoreInvoke
    method cvCloneImage (line 221) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvReleaseImage (line 228) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvAddWeighted (line 240) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvLine (line 259) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvPolyLine (line 279) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvRectangle (line 294) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvRectangleR (line 308) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvCircle (line 323) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvEllipse (line 341) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvDrawContours (line 357) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvFillConvexPoly (line 371) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvInitFont (line 387) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvPutText (line 399) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]
    method cvGetTextSize (line 409) | [DllImport(OPENCV_CORE_LIBRARY, CallingConvention = CvCallingConvention)]

FILE: Source/UI.Image/Base/CvInvoke.cs
  type WindowSizing (line 31) | internal enum WindowSizing : int
  class CvInvoke (line 40) | static class CvInvoke
    method cvNamedWindow (line 46) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvShowImage (line 49) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvWaitKey (line 52) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvDestroyAllWindows (line 55) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...
    method cvGetWindowProperty (line 58) | [DllImport(OPENCV_HIGHGUI_LIBRARY, CallingConvention = CvCallingConven...

FILE: Source/UI.Image/Drawing.cs
  class ColorCvScalarConversionExtensions (line 33) | internal static class ColorCvScalarConversionExtensions
    method ToCvScalar (line 35) | public static CvScalar ToCvScalar(this Bgr<byte> color)
    method ToCvScalar (line 40) | public static CvScalar ToCvScalar(this Bgra<byte> color)
  class DrawingNativeImage (line 49) | public static class DrawingNativeImage
    method Draw (line 51) | internal unsafe static void Draw(Image<Bgr<byte>> image, byte opacity,...
    method DrawRectangle (line 72) | public unsafe static void DrawRectangle(this Image<Bgr<byte>> image, R...
    method DrawText (line 96) | public unsafe static void DrawText(this Image<Bgr<byte>> image, string...
    method Draw2DBox (line 116) | public unsafe static void Draw2DBox(this Image<Bgr<byte>> image, Box2D...
    method DrawEllipse (line 144) | public unsafe static void DrawEllipse(this Image<Bgr<byte>> image, Ell...
    method DrawPolygon (line 165) | public unsafe static void DrawPolygon(this Image<Bgr<byte>> image, Poi...
    method DrawCircle (line 191) | public unsafe static void DrawCircle(this Image<Bgr<byte>> image, Circ...
    method DrawCircles (line 210) | public unsafe static void DrawCircles(this Image<Bgr<byte>> image, IEn...
    method DrawAnnotation (line 235) | public static void DrawAnnotation(this Image<Bgr<byte>> image, Rectang...
  class Drawing (line 252) | public static class Drawing
    method Draw (line 254) | unsafe static void Draw(Bgr<byte>[,] image, byte opacity, Action<IplIm...
    method DrawRectangle (line 270) | public unsafe static void DrawRectangle(this Bgr<byte>[,] image, Recta...
    method DrawText (line 294) | public unsafe static void DrawText(this Bgr<byte>[,] image, string tex...
    method Draw2DBox (line 314) | public unsafe static void Draw2DBox(this Bgr<byte>[,] image, Box2D box...
    method DrawEllipse (line 342) | public unsafe static void DrawEllipse(this Bgr<byte>[,] image, Ellipse...
    method DrawPolygon (line 363) | public unsafe static void DrawPolygon(this Bgr<byte>[,] image, Point[]...
    method DrawCircle (line 389) | public unsafe static void DrawCircle(this Bgr<byte>[,] image, Circle c...
    method DrawCircles (line 408) | public unsafe static void DrawCircles(this Bgr<byte>[,] image, IEnumer...
    method DrawAnnotation (line 433) | public static void DrawAnnotation(this Bgr<byte>[,] image, Rectangle r...

FILE: Source/UI.Image/ImageUI.cs
  class ImageUI (line 29) | public static class ImageUI
    method CloseAll (line 34) | public static void CloseAll()
    method ShowDialog (line 45) | public static void ShowDialog(this Bgr<byte>[,] image, string windowTi...
    method Show (line 59) | public static void Show(this Bgr<byte>[,] image, string windowTitle = ...
Condensed preview — 91 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (467K chars).
[
  {
    "path": ".gitignore",
    "chars": 1513,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "Deploy/Licence.txt",
    "chars": 11357,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "Deploy/Nuget/Push.ps1",
    "chars": 366,
    "preview": "#--references: \n#  list files: https://medium.com/@victorleungtw/replace-text-in-xml-files-with-powershell-504d3e37a058\n"
  },
  {
    "path": "Directory.Build.props",
    "chars": 261,
    "preview": "<Project>\n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <LangVersion>preview</LangVersio"
  },
  {
    "path": "DotImaging.sln",
    "chars": 9591,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.2"
  },
  {
    "path": "README.md",
    "chars": 5080,
    "preview": "<p align=\"center\">\r\n    <a href=\"https://www.nuget.org/profiles/dajuric\"> <img src=\"Deploy/Logo/logo-big.png\" alt=\"DotIm"
  },
  {
    "path": "Samples/Sample.Basic/Program.cs",
    "chars": 1107,
    "preview": "using DotImaging;\nusing System.Drawing;\nusing System;\nusing System.IO;\n\nnamespace BasicImageOperations\n{\n    static cla"
  },
  {
    "path": "Samples/Sample.Basic/Sample.Basic.csproj",
    "chars": 596,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Outpu"
  },
  {
    "path": "Samples/Sample.Capture/Program.cs",
    "chars": 2238,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Samples/Sample.Capture/Sample.Capture.csproj",
    "chars": 746,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Samples/Sample.CaptureAndRecord/Program.cs",
    "chars": 2220,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Samples/Sample.CaptureAndRecord/Sample.CaptureAndRecord.csproj",
    "chars": 746,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Samples/Sample.ImageExtractor/Program.cs",
    "chars": 3279,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Samples/Sample.ImageExtractor/Sample.ImageExtractor.csproj",
    "chars": 746,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Samples/Sample.Interop/Program.cs",
    "chars": 2913,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Samples/Sample.Interop/Sample.Interop.csproj",
    "chars": 689,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Samples/Sample.MultipleCameraCapture/Program.cs",
    "chars": 2451,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Samples/Sample.MultipleCameraCapture/Sample.MultipleCameraCapture.csproj",
    "chars": 598,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Samples/Sample.UI/Program.cs",
    "chars": 2192,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Samples/Sample.UI/Sample.UI.csproj",
    "chars": 693,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>net47</TargetFrameworks>\n  </PropertyGroup>"
  },
  {
    "path": "Samples/Sample.VideoStreaming/Program.cs",
    "chars": 2310,
    "preview": "using DotImaging;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\n\nnamespace YoutubeStreaming\n{\n    class Prog"
  },
  {
    "path": "Samples/Sample.VideoStreaming/Sample.VideoStreaming.csproj",
    "chars": 667,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Platf"
  },
  {
    "path": "Source/BitmapInterop/.nuSpec/readmeImage.Bitmap.txt",
    "chars": 539,
    "preview": "Provides extensions for interoperability with System.Drawing.Bitmap, Point, PointF, Color and drawing extensions.\n\n1) A"
  },
  {
    "path": "Source/BitmapInterop/BmpExtensions/BitmapConversion.cs",
    "chars": 12194,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/BitmapInterop/BmpExtensions/BmpIO.cs",
    "chars": 4054,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/BitmapInterop/BmpExtensions/ColorConversion.cs",
    "chars": 2680,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/BitmapInterop/Image.BitmapInterop.csproj",
    "chars": 1702,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <AssemblyName>DotImaging.BitmapInterop</AssemblyName>\n    <Ro"
  },
  {
    "path": "Source/IO/.nuSpec/readmeIO.txt",
    "chars": 1499,
    "preview": "Unified stream-like platform-abstract API for IO video access: web-camera support, various video-format reading / writi"
  },
  {
    "path": "Source/IO/Base/Abstract/ImageStream.cs",
    "chars": 4314,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Base/Abstract/ImageStreamReader.cs",
    "chars": 8737,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Base/Abstract/ImageStreamWriter.cs",
    "chars": 4360,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Base/CvInvoke.cs",
    "chars": 12567,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/IO.csproj",
    "chars": 2418,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <Platforms>x64</Platforms>\n    <AssemblyName>DotImaging.IO</A"
  },
  {
    "path": "Source/IO/ImageIO.cs",
    "chars": 23782,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko"
  },
  {
    "path": "Source/IO/Readers/CameraCapture.cs",
    "chars": 6082,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Readers/FileCapture.cs",
    "chars": 4527,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Readers/ImageDirectoryCapture.cs",
    "chars": 7508,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Readers/VideoCaptureBase.cs",
    "chars": 3493,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko "
  },
  {
    "path": "Source/IO/Utilities/NaturalSortComparer.cs",
    "chars": 3632,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/IO/Utilities/PathExtensions.cs",
    "chars": 2359,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/IO/Writers/ImageWriterExtension.cs",
    "chars": 2565,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko"
  },
  {
    "path": "Source/IO/Writers/VideoWriter.cs",
    "chars": 6107,
    "preview": "#region Licence and Terms\r\n// DotImaging Framework\r\n// https://github.com/dajuric/dot-imaging\r\n//\r\n// Copyright © Darko"
  },
  {
    "path": "Source/IO.Web/.nuSpec/readmeIO.Web.txt",
    "chars": 1460,
    "preview": " Provides support for image or video download/streaming (direct video link or Youtube links).\n\n1) image loading:\n  \n   "
  },
  {
    "path": "Source/IO.Web/IO.Web.csproj",
    "chars": 1742,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <AssemblyName>DotImaging.IO.Web</AssemblyName>\n    <RootNames"
  },
  {
    "path": "Source/IO.Web/NamedPipeExtensions.cs",
    "chars": 8405,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/IO.Web/WebImageExtensions.cs",
    "chars": 2478,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/.nuSpec/readmeImage.txt",
    "chars": 1732,
    "preview": "Provides .NET native array imaging extensions. Color-spaces and channel depth conversion is included.\nImplements slim g"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorInfo.cs",
    "chars": 7888,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/Bgr.cs",
    "chars": 8321,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/Bgra.cs",
    "chars": 4183,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/Gray.cs",
    "chars": 3205,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/Hsv.cs",
    "chars": 4734,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/IColor.cs",
    "chars": 2305,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/ColorSpaces/Rgb.cs",
    "chars": 3417,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ColorTypeConversions/Converters/ColorConversionExtensions.cs",
    "chars": 14248,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/BasicExtensions.cs",
    "chars": 12208,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/ChannelMerger.cs",
    "chars": 5318,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/ChannelSplitter.cs",
    "chars": 5982,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/Convert.cs",
    "chars": 3200,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/Copy.cs",
    "chars": 12584,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Extensions/ImageFlipping.cs",
    "chars": 3891,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Image/Extensions/SpatialConvolution.cs",
    "chars": 6743,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Image.csproj",
    "chars": 1734,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <AssemblyName>DotImaging.Image</AssemblyName>\n    <RootNamesp"
  },
  {
    "path": "Source/Image/Interop/CvMat.cs",
    "chars": 7916,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Interop/IplImage.cs",
    "chars": 18163,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Image/Linq/ImagingLinq.cs",
    "chars": 9420,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/ParallelLauncher.cs",
    "chars": 2826,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Slice2D.cs",
    "chars": 4270,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Image/Unmanaged/IImage.cs",
    "chars": 2407,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Image/Unmanaged/Image'1.cs",
    "chars": 10264,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Box2D/Box2D.cs",
    "chars": 5747,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Circle/Circle.cs",
    "chars": 4960,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Circle/CircleF.cs",
    "chars": 5841,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Ellipse/Ellipse.cs",
    "chars": 5640,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Point/Point'1.cs",
    "chars": 2493,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/Primitives2D/Point/PointExtensions.cs",
    "chars": 20747,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Primitives2D.csproj",
    "chars": 1509,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <TargetFrameworks>netcoreapp2.2</TargetFrameworks>\n    <Assem"
  },
  {
    "path": "Source/Primitives2D/Rectangle/RectangleExtensions.cs",
    "chars": 7534,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/Primitives2D/Size/SizeExtensions.cs",
    "chars": 3430,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/UI.Image/.nuSpec/readmeUI.Image.txt",
    "chars": 198,
    "preview": "Portable standalone UI elements invokable as extensions (image display).\n\nimage show\n   Bgr<byte>[,] image = new Bgr<by"
  },
  {
    "path": "Source/UI.Image/Base/CvCoreInvoke.cs",
    "chars": 21175,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/UI.Image/Base/CvInvoke.cs",
    "chars": 2100,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Juri"
  },
  {
    "path": "Source/UI.Image/Drawing.cs",
    "chars": 18206,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/UI.Image/ImageUI.cs",
    "chars": 2564,
    "preview": "#region Licence and Terms\n// DotImaging Framework\n// https://github.com/dajuric/dot-imaging\n//\n// Copyright © Darko Jur"
  },
  {
    "path": "Source/UI.Image/UI.Image.csproj",
    "chars": 2494,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">  \n  <PropertyGroup>\n    <Platforms>x64</Platforms>\n    <AssemblyName>DotImaging.UI.Im"
  }
]

// ... and 6 more files (download for full content)

About this extraction

This page contains the full source code of the dajuric/dot-imaging GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 91 files (432.8 KB), approximately 103.7k tokens, and a symbol index with 538 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!