### **ImageSharp** is a new, fully featured, fully managed, cross-platform, 2D graphics API.
-ImageSharp is a new, fully featured, fully managed, cross-platform, 2D graphics library.
-Designed to simplify image processing, ImageSharp brings you an incredibly powerful yet beautifully simple API.
+Designed to democratize image processing, ImageSharp brings you an incredibly powerful yet beautifully simple API.
-ImageSharp is designed from the ground up to be flexible and extensible. The library provides API endpoints for common image processing operations and the building blocks to allow for the development of additional operations.
+Compared to `System.Drawing` we have been able to develop something much more flexible, easier to code against, and much, much less prone to memory leaks. Gone are system-wide process-locks; ImageSharp images are thread-safe and fully supported in web environments.
-Built against [.NET 8](https://docs.microsoft.com/en-us/dotnet/standard/net-standard), ImageSharp can be used in device, cloud, and embedded/IoT scenarios.
+Built against .NET Standard 1.3 ImageSharp can be used in device, cloud, and embedded/IoT scenarios.
+### Documentation
+For all SixLabors projects, including ImageSharp:
+https://sixlabors.github.io/docs/
-## License
-
-- ImageSharp is licensed under the [Six Labors Split License, Version 1.0](https://github.com/SixLabors/ImageSharp/blob/main/LICENSE)
+### Installation
-## Support Six Labors
+Install stable releases via Nuget; development releases are available via MyGet.
-Support the efforts of the development of the Six Labors projects.
- - [Purchase a Commercial License :heart:](https://sixlabors.com/pricing/)
- - [Become a sponsor via GitHub Sponsors :heart:]( https://github.com/sponsors/SixLabors)
- - [Become a sponsor via Open Collective :heart:](https://opencollective.com/sixlabors)
+| Package Name | Release (NuGet) | Nightly (MyGet) |
+|--------------------------------|-----------------|-----------------|
+| `SixLabors.ImageSharp` | [](https://www.nuget.org/packages/SixLabors.ImageSharp/) | [](https://www.myget.org/feed/sixlabors/package/nuget/SixLabors.ImageSharp) |
+| `SixLabors.ImageSharp.Drawing` | [](https://www.nuget.org/packages/SixLabors.ImageSharp.Drawing/) | [](https://www.myget.org/feed/sixlabors/package/nuget/SixLabors.ImageSharp.Drawing) |
-## Documentation
+### Packages
-- [Detailed documentation](https://sixlabors.github.io/docs/) for the ImageSharp API is available. This includes additional conceptual documentation to help you get started.
-- Our [Samples Repository](https://github.com/SixLabors/Samples/tree/main/ImageSharp) is also available containing buildable code samples demonstrating common activities.
+The **ImageSharp** library is made up of multiple packages:
+- **SixLabors.ImageSharp**
+ - Contains the generic `Image` class, PixelFormats, Primitives, Configuration, and other core functionality.
+ - The `IImageFormat` interface, Jpeg, Png, Bmp, and Gif formats.
+ - Transform methods like Resize, Crop, Skew, Rotate - Anything that alters the dimensions of the image.
+ - Non-transform methods like Gaussian Blur, Pixelate, Edge Detection - Anything that maintains the original image dimensions.
-## Questions
+- **SixLabors.ImageSharp.Drawing**
+ - Brushes and various drawing algorithms, including drawing images.
+ - Various vector drawing methods for drawing paths, polygons etc.
+ - Text drawing.
-- Do you have questions? Please [join our Discussions Forum](https://github.com/SixLabors/ImageSharp/discussions/categories/q-a). Do not open issues for questions.
-- For feature ideas please [join our Discussions Forum](https://github.com/SixLabors/ImageSharp/discussions/categories/ideas) and we'll be happy to discuss.
-- Please read our [Contribution Guide](https://github.com/SixLabors/ImageSharp/blob/main/.github/CONTRIBUTING.md) before opening issues or pull requests!
+### Build Status
-## Code of Conduct
-This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org/) to clarify expected behavior in our community.
-For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
+| |Build Status|Code Coverage|
+|-------------|:----------:|:-----------:|
+|**Linux/Mac**|[](https://travis-ci.org/SixLabors/ImageSharp)|[](https://codecov.io/gh/SixLabors/ImageSharp)|
+|**Windows** |[](https://ci.appveyor.com/project/six-labors/imagesharp/branch/master)|[](https://codecov.io/gh/SixLabors/ImageSharp)|
-## Installation
+### Questions?
-Install stable releases via Nuget; development releases are available via MyGet.
+- Do you have questions? We are happy to help! Please [join our gitter channel](https://gitter.im/ImageSharp/General), or ask them on [stackoverflow](https://stackoverflow.com) using the `ImageSharp` tag. **Do not** open issues for questions!
+- Please read our [Contribution Guide](https://github.com/SixLabors/ImageSharp/blob/master/.github/CONTRIBUTING.md) before opening issues or pull requests!
-| Package Name | Release (NuGet) | Nightly (Feedz.io) |
-|--------------------------------|-----------------|-----------------|
-| `SixLabors.ImageSharp` | [](https://www.nuget.org/packages/SixLabors.ImageSharp/) | [](https://f.feedz.io/sixlabors/sixlabors/nuget/index.json) |
+### API
+
+Our API is designed to be simple to consume. Here's an example of the code required to resize an image using the default Bicubic resampler then turn the colors into their grayscale equivalent using the BT709 standard matrix.
+
+On platforms supporting netstandard 1.3+
+
+```csharp
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.Processing;
+
+// Image.Load(string path) is a shortcut for our default type.
+// Other pixel formats use Image.Load(string path))
+using (Image image = Image.Load("foo.jpg"))
+{
+ image.Mutate(x => x
+ .Resize(image.Width / 2, image.Height / 2)
+ .Grayscale());
+ image.Save("bar.jpg"); // Automatic encoder selected based on extension.
+}
+```
+
+Setting individual pixel values can be performed as follows:
+
+```csharp
+using SixLabors.ImageSharp;
+using SixLabors.ImageSharp.PixelFormats;
+
+// Individual pixels
+using (Image image = new Image(400, 400))
+{
+ image[200, 200] = Rgba32.White;
+}
+```
+
+`Rgba32` is our default PixelFormat, equivalent to `System.Drawing Color`. For advanced pixel format usage there are multiple [PixelFormat implementations](https://github.com/SixLabors/ImageSharp/tree/master/src/ImageSharp/PixelFormats) available allowing developers to implement their own color models in the same manner as Microsoft XNA Game Studio and MonoGame.
-## Manual build
+For more examples check out:
+- [Our Documentation](https://sixlabors.github.io/docs/)
+- Our [Samples Repository](https://github.com/SixLabors/Samples/tree/master/ImageSharp)
+- The [beta1 blog post](https://sixlabors.com/blog/announcing-imagesharp-beta-1/)
+
+### Manual build
If you prefer, you can compile ImageSharp yourself (please do and help!)
-- Using [Visual Studio 2022](https://visualstudio.microsoft.com/vs/)
+- Using [Visual Studio 2017](https://visualstudio.microsoft.com/vs/)
- Make sure you have the latest version installed
- - Make sure you have [the .NET 8 SDK](https://www.microsoft.com/net/core#windows) installed
+ - Make sure you have [the .NET Core 2.1 SDK](https://www.microsoft.com/net/core#windows) installed
Alternatively, you can work from command line and/or with a lightweight editor on **both Linux/Unix and Windows**:
- [Visual Studio Code](https://code.visualstudio.com/) with [C# Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp)
- [.NET Core](https://www.microsoft.com/net/core#linuxubuntu)
-To clone ImageSharp locally, click the "Clone in [YOUR_OS]" button above or run the following git commands:
+To clone ImageSharp locally click the "Clone in Windows" button above or run the following git commands.
```bash
git clone https://github.com/SixLabors/ImageSharp
```
-Then set the following config to ensure blame commands ignore mass reformatting commits.
-
-```bash
-git config blame.ignoreRevsFile .git-blame-ignore-revs
-```
-
-If working with Windows please ensure that you have enabled long file paths in git (run as Administrator).
-
-```bash
-git config --system core.longpaths true
-```
-
-This repository uses [Git Large File Storage](https://docs.github.com/en/github/managing-large-files/installing-git-large-file-storage). Please follow the linked instructions to ensure you have it set up in your environment.
+### Submodules
-This repository contains [Git Submodules](https://blog.github.com/2016-02-01-working-with-submodules/). To add the submodules to the project, navigate to the repository root and type:
+This repository contains [git submodules](https://blog.github.com/2016-02-01-working-with-submodules/). To add the submodules to the project, navigate to the repository root and type:
``` bash
git submodule update --init --recursive
```
-## How can you help?
+### How can you help?
-Please... Spread the word, contribute algorithms, submit performance improvements, unit tests, no input is too little. Make sure to read our [Contribution Guide](https://github.com/SixLabors/ImageSharp/blob/main/.github/CONTRIBUTING.md) before opening a PR.
+Please... Spread the word, contribute algorithms, submit performance improvements, unit tests, no input is too little. Make sure to read our [Contribution Guide](https://github.com/SixLabors/ImageSharp/blob/master/.github/CONTRIBUTING.md) before opening a PR.
-Useful tools for development and links to specifications can be found in our wikipage: [Useful-tools-and-links](https://github.com/SixLabors/ImageSharp/wiki/Useful-tools-and-links).
-
-## The ImageSharp Team
+### The ImageSharp Team
+Grand High Eternal Dictator
- [James Jackson-South](https://github.com/jimbobsquarepants)
+
+Core Team
- [Dirk Lemstra](https://github.com/dlemstra)
- [Anton Firsov](https://github.com/antonfirsov)
- [Scott Williams](https://github.com/tocsoft)
-- [Brian Popow](https://github.com/brianpopow)
----
-
-
-
-
-
- Special thanks to [JetBrains](https://www.jetbrains.com/?from=ImageSharp) for supporting us with open-source licenses for their IDEs.
-
+### Backers
+
+Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/imagesharp#backer)]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Sponsors
+
+Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/imagesharp#sponsor)]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SixLabors.ImageSharp.props b/SixLabors.ImageSharp.props
deleted file mode 100644
index 353dce25e7..0000000000
--- a/SixLabors.ImageSharp.props
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT
deleted file mode 100644
index eaf9f73f07..0000000000
--- a/THIRD-PARTY-NOTICES.TXT
+++ /dev/null
@@ -1,32 +0,0 @@
-ImageSharp uses third-party libraries or other resources that may be
-distributed under licenses different than ImageSharp itself.
-
-In the event that we accidentally failed to list a required notice, please
-bring it to our attention by posting an issue.
-
-The attached notices are provided for information only.
-
-
-License notice for Zlib
------
-
-DeflateStream implementation adapted from SharpZipLib.
-Licensed under MIT.
-https://github.com/icsharpcode/SharpZipLib
-
-
-Crc32 and Adler32 SIMD implementation adapted from Chromium.
-Licensed under BSD 3-Clause "New" or "Revised" License.
-https://github.com/chromium/chromium
-
-
-License notice for Stream Read/Write Extensions
------
-
-Licensed to the .NET Foundation under one or more agreements.
-The .NET Foundation licenses this file to you under the MIT license.
-See the LICENSE file in the CoreFX project root for more information.
-
-https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/LICENSE.TXT
-https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L742
-https://github.com/dotnet/corefx/blob/17300169760c61a90cab8d913636c1058a30a8c1/src/Common/src/CoreLib/System/IO/Stream.cs#L775
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000000..2cc5182d39
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,69 @@
+version: 1.0.0.{build}
+image: Visual Studio 2017
+
+# prevent the double build when a branch has an active PR
+skip_branch_with_pr: true
+
+environment:
+ matrix:
+ - target_framework: netcoreapp2.1
+ is_32bit: False
+
+ - target_framework: netcoreapp2.1
+ is_32bit: True
+
+ - target_framework: net472
+ is_32bit: False
+
+ - target_framework: net472
+ is_32bit: True
+
+ - target_framework: net462
+ is_32bit: False
+
+ - target_framework: net462
+ is_32bit: True
+
+ #- target_framework: mono
+ # is_32bit: False
+ #- target_framework: mono
+ # is_32bit: True
+ #- target_framework: net47
+ # is_32bit: False
+ #- target_framework: net47
+ # is_32bit: True
+
+install:
+ - ps: |
+ if ($env:target_framework -eq "mono") {
+ if ($env:is_32bit -eq "True") {
+ cinst mono --x86
+ } else {
+ cinst mono
+ }
+ }
+
+before_build:
+ - git submodule -q update --init
+ - cmd: dotnet --info
+
+build_script:
+- cmd: build.cmd
+
+test_script:
+- ps: .\run-tests.ps1 $env:target_framework $env:is_32bit
+
+after_test:
+ - cmd: appveyor PushArtifact "artifacts\SixLabors.ImageSharp.%APPVEYOR_BUILD_VERSION%.nupkg"
+ - cmd: appveyor PushArtifact "artifacts\SixLabors.ImageSharp.Drawing.%APPVEYOR_BUILD_VERSION%.nupkg"
+
+deploy:
+ # MyGet Deployment for builds & releases
+ - provider: NuGet
+ server: https://www.myget.org/F/sixlabors/api/v2/package
+ symbol_server: https://www.myget.org/F/sixlabors/symbols/api/v2/package
+ api_key:
+ secure: V/lEHP0UeMWIpWd0fiNlY2IgbCnJKQlGdRksECdJbOBdaE20Fl0RNL7WyqHe02o4
+ artifact: /.*\.nupkg/
+ on:
+ branch: master
\ No newline at end of file
diff --git a/build.cmd b/build.cmd
new file mode 100644
index 0000000000..6372b41253
--- /dev/null
+++ b/build.cmd
@@ -0,0 +1,17 @@
+@echo Off
+
+PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '.\build.ps1'"
+
+if not "%errorlevel%"=="0" goto failure
+
+:success
+ECHO successfully built project
+REM exit 0
+goto end
+
+:failure
+ECHO failed to build.
+REM exit -1
+goto end
+
+:end
\ No newline at end of file
diff --git a/build.ps1 b/build.ps1
new file mode 100644
index 0000000000..215b551170
--- /dev/null
+++ b/build.ps1
@@ -0,0 +1,122 @@
+
+# lets calulat the correct version here
+$fallbackVersion = "1.0.0";
+$version = ''
+
+$tagRegex = '^v?(\d+\.\d+\.\d+)(-([a-zA-Z]+)\.?(\d*))?$'
+
+# we are running on the build server
+$isVersionTag = $env:APPVEYOR_REPO_TAG_NAME -match $tagRegex
+
+ if($isVersionTag) {
+
+ Write-Debug "Building commit tagged with a compatable version number"
+
+ $version = $matches[1]
+ $postTag = $matches[3]
+ $count = $matches[4]
+ Write-Debug "version number: ${version} post tag: ${postTag} count: ${count}"
+ if("$postTag" -ne ""){
+ $version = "${version}-${postTag}"
+ }
+ if("$count" -ne ""){
+ # for consistancy with previous releases we pad the counter to only 4 places
+ $padded = $count.Trim().Trim('0').PadLeft(4,"0");
+ Write-Debug "count '$count', padded '${padded}'"
+
+ $version = "${version}${padded}"
+ }
+ }
+ else {
+
+ Write-Debug "Untagged"
+ $lastTag = (git tag --list --sort=-taggerdate) | Out-String
+ $list = $lastTag.Split("`n")
+ foreach ($tag in $list) {
+
+ Write-Debug "testing ${tag}"
+ $tag = $tag.Trim();
+ if($tag -match $tagRegex){
+ Write-Debug "matched ${tag}"
+ $version = $matches[1];
+ break;
+ }
+ }
+
+ if("$version" -eq ""){
+ $version = $fallbackVersion
+ Write-Debug "Failed to discover base version Fallback to '${version}'"
+ }else{
+
+ Write-Debug "Discovered base version from tags '${version}'"
+ }
+
+ $buildNumber = $env:APPVEYOR_BUILD_NUMBER
+
+ # build number replacement is padded to 6 places
+ $buildNumber = "$buildNumber".Trim().Trim('0').PadLeft(6,"0");
+ if("$env:APPVEYOR_PULL_REQUEST_NUMBER" -ne ""){
+ Write-Debug "building a PR"
+
+ $prNumber = "$env:APPVEYOR_PULL_REQUEST_NUMBER".Trim().Trim('0').PadLeft(5,"0");
+ # this is a PR
+ $version = "${version}-PullRequest${prNumber}${buildNumber}";
+ }else{
+ Write-Debug "building a branch commit"
+
+ # this is a general branch commit
+ $branch = $env:APPVEYOR_REPO_BRANCH
+
+ if("$branch" -eq ""){
+ $branch = ((git rev-parse --abbrev-ref HEAD) | Out-String).Trim()
+
+ if("$branch" -eq ""){
+ $branch = "unknown"
+ }
+ }
+
+ $branch = $branch.Replace("/","-").ToLower()
+
+ if($branch.ToLower() -eq "master"){
+ $branch = "dev"
+ }
+
+ $version = "${version}-${branch}${buildNumber}";
+ }
+ }
+
+if("$env:APPVEYOR_API_URL" -ne ""){
+ # update appveyor build number for this build
+ Invoke-RestMethod -Method "PUT" `
+ -Uri "${env:APPVEYOR_API_URL}api/build" `
+ -Body "{version:'${version}'}" `
+ -ContentType "application/json"
+}
+
+Write-Host "Building version '${version}'"
+dotnet restore /p:packageversion=$version /p:DisableImplicitNuGetFallbackFolder=true
+
+Write-Host "Building projects"
+dotnet build -c Release /p:packageversion=$version
+
+if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
+
+#
+# TODO: DO WE NEED TO RUN TESTS IMPLICITLY?
+#
+# if ( $env:CI -ne "True") {
+# cd ./tests/ImageSharp.Tests/
+# dotnet xunit -nobuild -c Release -f netcoreapp2.0 --fx-version 2.0.0
+# ./RunExtendedTests.cmd
+# cd ../..
+# }
+#
+
+if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
+
+Write-Host "Packaging projects"
+dotnet pack ./src/ImageSharp/ -c Release --output ../../artifacts --no-build /p:packageversion=$version
+if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
+
+dotnet pack ./src/ImageSharp.Drawing/ -c Release --output ../../artifacts --no-build /p:packageversion=$version
+if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
diff --git a/build/icons/imagesharp-logo-128.png b/build/icons/imagesharp-logo-128.png
new file mode 100644
index 0000000000..b60966e042
Binary files /dev/null and b/build/icons/imagesharp-logo-128.png differ
diff --git a/build/icons/imagesharp-logo-256.png b/build/icons/imagesharp-logo-256.png
new file mode 100644
index 0000000000..075f498ba0
Binary files /dev/null and b/build/icons/imagesharp-logo-256.png differ
diff --git a/build/icons/imagesharp-logo-32.png b/build/icons/imagesharp-logo-32.png
new file mode 100644
index 0000000000..48e9ab718c
Binary files /dev/null and b/build/icons/imagesharp-logo-32.png differ
diff --git a/build/icons/imagesharp-logo-512.png b/build/icons/imagesharp-logo-512.png
new file mode 100644
index 0000000000..053dba951f
Binary files /dev/null and b/build/icons/imagesharp-logo-512.png differ
diff --git a/build/icons/imagesharp-logo-64.png b/build/icons/imagesharp-logo-64.png
new file mode 100644
index 0000000000..2d9a0045e4
Binary files /dev/null and b/build/icons/imagesharp-logo-64.png differ
diff --git a/build/icons/imagesharp-logo.png b/build/icons/imagesharp-logo.png
new file mode 100644
index 0000000000..053dba951f
Binary files /dev/null and b/build/icons/imagesharp-logo.png differ
diff --git a/build/icons/imagesharp-logo.svg b/build/icons/imagesharp-logo.svg
new file mode 100644
index 0000000000..620287457a
--- /dev/null
+++ b/build/icons/imagesharp-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ci-build.ps1 b/ci-build.ps1
deleted file mode 100644
index d45af6ff4d..0000000000
--- a/ci-build.ps1
+++ /dev/null
@@ -1,11 +0,0 @@
-param(
- [Parameter(Mandatory = $true, Position = 0)]
- [string]$targetFramework
-)
-
-dotnet clean -c Release
-
-$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY"
-
-# Building for a specific framework.
-dotnet build -c Release -f $targetFramework /p:RepositoryUrl=$repositoryUrl
diff --git a/ci-pack.ps1 b/ci-pack.ps1
deleted file mode 100644
index 55c69fb590..0000000000
--- a/ci-pack.ps1
+++ /dev/null
@@ -1,6 +0,0 @@
-dotnet clean -c Release
-
-$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY"
-
-# Building for packing and publishing.
-dotnet pack -c Release -p:PackageOutputPath="$PSScriptRoot/artifacts" -p:RepositoryUrl=$repositoryUrl
diff --git a/ci-test.ps1 b/ci-test.ps1
deleted file mode 100644
index d9bb0211a5..0000000000
--- a/ci-test.ps1
+++ /dev/null
@@ -1,37 +0,0 @@
-param(
- [Parameter(Mandatory, Position = 0)]
- [string]$os,
- [Parameter(Mandatory, Position = 1)]
- [string]$targetFramework,
- [Parameter(Mandatory, Position = 2)]
- [string]$platform,
- [Parameter(Mandatory, Position = 3)]
- [string]$codecov,
- [Parameter(Position = 4)]
- [string]$codecovProfile = 'Release'
-)
-
-$netFxRegex = '^net\d+'
-
-if ($codecov -eq 'true') {
-
- # Allow toggling of profile to workaround any potential JIT errors caused by code injection.
- dotnet clean -c $codecovProfile
- dotnet test --collect "XPlat Code Coverage" --settings .\tests\coverlet.runsettings -c $codecovProfile -f $targetFramework /p:CodeCov=true
-}
-elseif ($platform -eq '-x86' -and $targetFramework -match $netFxRegex) {
-
- # xunit doesn't run on core with NET SDK 3.1+.
- # xunit doesn't actually understand -x64 as an option.
- #
- # xunit requires explicit path.
- Set-Location $env:XUNIT_PATH
-
- dotnet xunit --no-build -c Release -f $targetFramework ${fxVersion} $platform
-
- Set-Location $PSScriptRoot
-}
-else {
-
- dotnet test --no-build -c Release -f $targetFramework --blame --diag .tests\Images\ActualOutput\diaglog.txt
-}
diff --git a/codecov.yml b/codecov.yml
index 310eefb8c2..ae6dd5f6bf 100644
--- a/codecov.yml
+++ b/codecov.yml
@@ -1,22 +1,4 @@
-# Documentation: https://docs.codecov.io/docs/codecov-yaml
+ignore:
+ "src/ImageSharp/Common/Helpers/DebugGuard.cs"
-codecov:
- # Avoid "Missing base report"
- # https://github.com/codecov/support/issues/363
- # https://docs.codecov.io/docs/comparing-commits
- allow_coverage_offsets: true
-
- # Avoid Report Expired
- # https://docs.codecov.io/docs/codecov-yaml#section-expired-reports
- max_report_age: off
-
-coverage:
- # Use integer precision
- # https://docs.codecov.com/docs/codecovyml-reference#coverageprecision
- precision: 0
-
- # Explicitly control coverage status checks
- # https://docs.codecov.com/docs/commit-status#disabling-a-status
- status:
- project: on
- patch: off
+
\ No newline at end of file
diff --git a/run-tests.ps1 b/run-tests.ps1
new file mode 100644
index 0000000000..4aeaa14908
--- /dev/null
+++ b/run-tests.ps1
@@ -0,0 +1,112 @@
+param(
+ [string]$targetFramework,
+ [string]$is32Bit = "False"
+)
+
+if (!$targetFramework){
+ Write-Host "run-tests.ps1 ERROR: targetFramework is undefined!"
+ exit 1
+}
+
+function VerifyPath($path, $errorMessage) {
+ if (!(Test-Path -Path $path)) {
+ Write-Host "run-tests.ps1 $errorMessage `n $xunitRunnerPath"
+ exit 1
+ }
+}
+
+function CheckSubmoduleStatus() {
+ $submoduleStatus = (git submodule status) | Out-String
+ # if the result string is empty, the command failed to run (we didn't capture the error stream)
+ if ($submoduleStatus) {
+ # git has been called successfully, what about the status?
+ if (($submoduleStatus -match "\-") -or ($submoduleStatus -match "\(\(null\)\)"))
+ {
+ # submodule has not been initialized!
+ return 2;
+ }
+ elseif ($submoduleStatus -match "\+")
+ {
+ # submodule is not synced:
+ return 1;
+ }
+ else {
+ # everything fine:
+ return 0;
+ }
+ } else {
+ # git call failed, so we should warn
+ return 3;
+ }
+}
+
+
+if ( ($targetFramework -eq "netcoreapp2.1") -and ($env:CI -eq "True") -and ($is32Bit -ne "True")) {
+ # We execute CodeCoverage.cmd only for one specific job on CI (netcoreapp2.1 + 64bit )
+ $testRunnerCmd = ".\tests\CodeCoverage\CodeCoverage.cmd"
+}
+elseif ($targetFramework -eq "mono") {
+ $testDllPath = "$PSScriptRoot\tests\ImageSharp.Tests\bin\Release\net462\SixLabors.ImageSharp.Tests.dll"
+ VerifyPath($testDllPath, "test dll missing:")
+
+ $xunitRunnerPath = "${env:HOMEPATH}\.nuget\packages\xunit.runner.console\2.3.1\tools\net452\"
+
+ VerifyPath($xunitRunnerPath, "xunit console runner is missing on path:")
+
+ cd "$xunitRunnerPath"
+
+ if ($is32Bit -ne "True") {
+ $monoPath = "${env:PROGRAMFILES}\Mono\bin\mono.exe"
+ }
+ else {
+ $monoPath = "${env:ProgramFiles(x86)}\Mono\bin\mono.exe"
+ }
+
+ VerifyPath($monoPath, "mono runtime missing:")
+
+ $testRunnerCmd = "& `"${monoPath}`" .\xunit.console.exe `"${testDllPath}`""
+}
+else {
+ cd .\tests\ImageSharp.Tests
+ $xunitArgs = "-nobuild -c Release -framework $targetFramework"
+
+ if ($targetFramework -eq "netcoreapp2.1") {
+ # There were issues matching the correct installed runtime if we do not specify it explicitly:
+ $xunitArgs += " --fx-version 2.1.0"
+ }
+
+ if ($is32Bit -eq "True") {
+ $xunitArgs += " -x86"
+ }
+
+ $testRunnerCmd = "dotnet xunit $xunitArgs"
+}
+
+Write-Host "running:"
+Write-Host $testRunnerCmd
+Write-Host "..."
+
+Invoke-Expression $testRunnerCmd
+
+cd $PSScriptRoot
+
+$exitCodeOfTests = $LASTEXITCODE;
+
+if (0 -ne ([int]$exitCodeOfTests)) {
+ # check submodule status
+ $submoduleStatus = CheckSubmoduleStatus
+ if ([int]$submoduleStatus -eq 1) {
+ # not synced
+ Write-Host -ForegroundColor Yellow "Check if submodules are up to date. You can use 'git submodule update' to fix this";
+ } elseif ($submoduleStatus -eq 2) {
+ # not initialized
+ Write-Host -ForegroundColor Yellow "Check if submodules are initialized. You can run 'git submodule init' to initialize them."
+ } elseif ($submoduleStatus -eq 3) {
+ # git not found, maybe submodules not synced?
+ Write-Host -ForegroundColor Yellow "Could not check if submodules are initialized correctly. Maybe git is not installed?"
+ } else {
+ #Write-Host "Submodules are up to date";
+ }
+}
+
+exit $exitCodeOfTests
diff --git a/shared-infrastructure b/shared-infrastructure
deleted file mode 160000
index 57699ffb79..0000000000
--- a/shared-infrastructure
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 57699ffb797bc2389c5d6cbb3b1800f2eb5fb947
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
deleted file mode 100644
index cfc3d82225..0000000000
--- a/src/Directory.Build.props
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
- ..\ImageSharp.ruleset
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
deleted file mode 100644
index c15c2a90cc..0000000000
--- a/src/Directory.Build.targets
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
new file mode 100644
index 0000000000..6f5cabb09b
--- /dev/null
+++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
@@ -0,0 +1,53 @@
+
+
+ SixLabors.ImageSharp.Drawing
+ SixLabors and contributors
+ Six Labors
+ Copyright (c) Six Labors and contributors.
+ SixLabors.ImageSharp
+ An extension to ImageSharp that allows the drawing of images, paths, and text.
+ en
+
+ $(packageversion)
+ 0.0.1
+ netcoreapp2.1;netstandard1.3;netstandard2.0
+ 7.3
+ true
+ true
+ SixLabors.ImageSharp.Drawing
+ SixLabors.ImageSharp.Drawing
+ Image Draw Shape Path Font
+ https://raw.githubusercontent.com/SixLabors/Branding/master/icons/imagesharp/sixlabors.imagesharp.128.png
+ https://github.com/SixLabors/ImageSharp
+ http://www.apache.org/licenses/LICENSE-2.0
+ git
+ https://github.com/SixLabors/ImageSharp
+ full
+ portable
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\standards\SixLabors.ruleset
+ SixLabors.ImageSharp
+
+
+
+ true
+
+
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Primitives/Region.cs b/src/ImageSharp.Drawing/Primitives/Region.cs
new file mode 100644
index 0000000000..27f039f122
--- /dev/null
+++ b/src/ImageSharp.Drawing/Primitives/Region.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Primitives
+{
+ ///
+ /// Represents a region of an image.
+ ///
+ public abstract class Region
+ {
+ ///
+ /// Gets the maximum number of intersections to could be returned.
+ ///
+ public abstract int MaxIntersections { get; }
+
+ ///
+ /// Gets the bounding box that entirely surrounds this region.
+ ///
+ ///
+ /// This should always contains all possible points returned from .
+ ///
+ public abstract Rectangle Bounds { get; }
+
+ ///
+ /// Scans the X axis for intersections at the Y axis position.
+ ///
+ /// The position along the y axis to find intersections.
+ /// The buffer.
+ /// A instance in the context of the caller.
+ /// The number of intersections found.
+ public abstract int Scan(float y, Span buffer, Configuration configuration);
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Primitives/ShapePath.cs b/src/ImageSharp.Drawing/Primitives/ShapePath.cs
new file mode 100644
index 0000000000..a4fef66a67
--- /dev/null
+++ b/src/ImageSharp.Drawing/Primitives/ShapePath.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Processing;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Primitives
+{
+ ///
+ /// A mapping between a and a region.
+ ///
+ internal class ShapePath : ShapeRegion
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The shape.
+ /// The pen to apply to the shape.
+ public ShapePath(IPath shape, IPen pen)
+ : base(shape.GenerateOutline(pen.StrokeWidth, pen.StrokePattern))
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs b/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs
new file mode 100644
index 0000000000..812744b895
--- /dev/null
+++ b/src/ImageSharp.Drawing/Primitives/ShapeRegion.cs
@@ -0,0 +1,65 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Buffers;
+
+using SixLabors.ImageSharp.Memory;
+using SixLabors.Memory;
+using SixLabors.Primitives;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Primitives
+{
+ ///
+ /// A mapping between a and a region.
+ ///
+ internal class ShapeRegion : Region
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The shape.
+ public ShapeRegion(IPath shape)
+ {
+ this.Shape = shape.AsClosedPath();
+ int left = (int)MathF.Floor(shape.Bounds.Left);
+ int top = (int)MathF.Floor(shape.Bounds.Top);
+
+ int right = (int)MathF.Ceiling(shape.Bounds.Right);
+ int bottom = (int)MathF.Ceiling(shape.Bounds.Bottom);
+ this.Bounds = Rectangle.FromLTRB(left, top, right, bottom);
+ }
+
+ ///
+ /// Gets the fillable shape
+ ///
+ public IPath Shape { get; }
+
+ ///
+ public override int MaxIntersections => this.Shape.MaxIntersections;
+
+ ///
+ public override Rectangle Bounds { get; }
+
+ ///
+ public override int Scan(float y, Span buffer, Configuration configuration)
+ {
+ var start = new PointF(this.Bounds.Left - 1, y);
+ var end = new PointF(this.Bounds.Right + 1, y);
+
+ using (IMemoryOwner tempBuffer = configuration.MemoryAllocator.Allocate(buffer.Length))
+ {
+ Span innerBuffer = tempBuffer.GetSpan();
+ int count = this.Shape.FindIntersections(start, end, innerBuffer);
+
+ for (int i = 0; i < count; i++)
+ {
+ buffer[i] = innerBuffer[i].X;
+ }
+
+ return count;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/BrushApplicator.cs b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs
new file mode 100644
index 0000000000..0c6e0d3b40
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/BrushApplicator.cs
@@ -0,0 +1,96 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Buffers;
+
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Memory;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// primitive that converts a point in to a color for discovering the fill color based on an implementation
+ ///
+ /// The pixel format.
+ ///
+ public abstract class BrushApplicator : IDisposable // disposable will be required if/when there is an ImageBrush
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The target.
+ /// The options.
+ internal BrushApplicator(ImageFrame target, GraphicsOptions options)
+ {
+ this.Target = target;
+ this.Options = options;
+ this.Blender = PixelOperations.Instance.GetPixelBlender(options);
+ }
+
+ ///
+ /// Gets the blender
+ ///
+ internal PixelBlender Blender { get; }
+
+ ///
+ /// Gets the destination
+ ///
+ protected ImageFrame Target { get; }
+
+ ///
+ /// Gets the blend percentage
+ ///
+ protected GraphicsOptions Options { get; private set; }
+
+ ///
+ /// Gets the color for a single pixel.
+ ///
+ /// The x coordinate.
+ /// The y coordinate.
+ /// The a that should be applied to the pixel.
+ internal abstract TPixel this[int x, int y] { get; }
+
+ ///
+ public abstract void Dispose();
+
+ ///
+ /// Applies the opacity weighting for each pixel in a scanline to the target based on the pattern contained in the brush.
+ ///
+ /// The a collection of opacity values between 0 and 1 to be merged with the brushed color value before being applied to the target.
+ /// The x position in the target pixel space that the start of the scanline data corresponds to.
+ /// The y position in the target pixel space that whole scanline corresponds to.
+ /// scanlineBuffer will be > scanlineWidth but provide and offset in case we want to share a larger buffer across runs.
+ internal virtual void Apply(Span scanline, int x, int y)
+ {
+ MemoryAllocator memoryAllocator = this.Target.MemoryAllocator;
+
+ using (IMemoryOwner amountBuffer = memoryAllocator.Allocate(scanline.Length))
+ using (IMemoryOwner overlay = memoryAllocator.Allocate(scanline.Length))
+ {
+ Span amountSpan = amountBuffer.GetSpan();
+ Span overlaySpan = overlay.GetSpan();
+
+ for (int i = 0; i < scanline.Length; i++)
+ {
+ if (this.Options.BlendPercentage < 1)
+ {
+ amountSpan[i] = scanline[i] * this.Options.BlendPercentage;
+ }
+ else
+ {
+ amountSpan[i] = scanline[i];
+ }
+
+ overlaySpan[i] = this[x + i, y];
+ }
+
+ Span destinationRow = this.Target.GetPixelRowSpan(y).Slice(x, scanline.Length);
+ this.Blender.Blend(this.Target.Configuration, destinationRow, destinationRow, overlaySpan, amountSpan);
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp.Drawing/Processing/Brushes.cs b/src/ImageSharp.Drawing/Processing/Brushes.cs
new file mode 100644
index 0000000000..c5e7a3e9ff
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Brushes.cs
@@ -0,0 +1,256 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// A collection of methods for creating generic brushes.
+ ///
+ /// A New
+ public static class Brushes
+ {
+ ///
+ /// Percent10 Hatch Pattern
+ ///
+ /// ---> x axis
+ /// ^
+ /// | y - axis
+ /// |
+ /// see PatternBrush for details about how to make new patterns work
+ private static readonly bool[,] Percent10Pattern =
+ {
+ { true, false, false, false },
+ { false, false, false, false },
+ { false, false, true, false },
+ { false, false, false, false }
+ };
+
+ ///
+ /// Percent20 pattern.
+ ///
+ private static readonly bool[,] Percent20Pattern =
+ {
+ { true, false, false, false },
+ { false, false, true, false },
+ { true, false, false, false },
+ { false, false, true, false }
+ };
+
+ ///
+ /// Horizontal Hatch Pattern
+ ///
+ private static readonly bool[,] HorizontalPattern =
+ {
+ { false },
+ { true },
+ { false },
+ { false }
+ };
+
+ ///
+ /// Min Pattern
+ ///
+ private static readonly bool[,] MinPattern =
+ {
+ { false },
+ { false },
+ { false },
+ { true }
+ };
+
+ ///
+ /// Vertical Pattern
+ ///
+ private static readonly bool[,] VerticalPattern =
+ {
+ { false, true, false, false },
+ };
+
+ ///
+ /// Forward Diagonal Pattern
+ ///
+ private static readonly bool[,] ForwardDiagonalPattern =
+ {
+ { false, false, false, true },
+ { false, false, true, false },
+ { false, true, false, false },
+ { true, false, false, false }
+ };
+
+ ///
+ /// Backward Diagonal Pattern
+ ///
+ private static readonly bool[,] BackwardDiagonalPattern =
+ {
+ { true, false, false, false },
+ { false, true, false, false },
+ { false, false, true, false },
+ { false, false, false, true }
+ };
+
+ ///
+ /// Create as brush that will paint a solid color
+ ///
+ /// The color.
+ /// The pixel format.
+ /// A New
+ public static SolidBrush Solid(TPixel color)
+ where TPixel : struct, IPixel
+ => new SolidBrush(color);
+
+ ///
+ /// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Percent10(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, Percent10Pattern);
+
+ ///
+ /// Create as brush that will paint a Percent10 Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Percent10(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, Percent10Pattern);
+
+ ///
+ /// Create as brush that will paint a Percent20 Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Percent20(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, Percent20Pattern);
+
+ ///
+ /// Create as brush that will paint a Percent20 Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Percent20(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, Percent20Pattern);
+
+ ///
+ /// Create as brush that will paint a Horizontal Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Horizontal(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, HorizontalPattern);
+
+ ///
+ /// Create as brush that will paint a Horizontal Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Horizontal(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, HorizontalPattern);
+
+ ///
+ /// Create as brush that will paint a Min Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Min(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, MinPattern);
+
+ ///
+ /// Create as brush that will paint a Min Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Min(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, MinPattern);
+
+ ///
+ /// Create as brush that will paint a Vertical Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Vertical(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, VerticalPattern);
+
+ ///
+ /// Create as brush that will paint a Vertical Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush Vertical(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, VerticalPattern);
+
+ ///
+ /// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush ForwardDiagonal(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, ForwardDiagonalPattern);
+
+ ///
+ /// Create as brush that will paint a Forward Diagonal Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush ForwardDiagonal(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, ForwardDiagonalPattern);
+
+ ///
+ /// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified foreground color and a
+ /// transparent background.
+ ///
+ /// Color of the foreground.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush BackwardDiagonal(TPixel foreColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, NamedColors.Transparent, BackwardDiagonalPattern);
+
+ ///
+ /// Create as brush that will paint a Backward Diagonal Hatch Pattern with the specified colors
+ ///
+ /// Color of the foreground.
+ /// Color of the background.
+ /// The pixel format.
+ /// A New
+ public static PatternBrush BackwardDiagonal(TPixel foreColor, TPixel backColor)
+ where TPixel : struct, IPixel
+ => new PatternBrush(foreColor, backColor, BackwardDiagonalPattern);
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/ColorStop{TPixel}.cs b/src/ImageSharp.Drawing/Processing/ColorStop{TPixel}.cs
new file mode 100644
index 0000000000..7fd0ba7cd3
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/ColorStop{TPixel}.cs
@@ -0,0 +1,39 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System.Diagnostics;
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// A struct that defines a single color stop.
+ ///
+ /// The pixel format.
+ [DebuggerDisplay("ColorStop({Ratio} -> {Color}")]
+ public struct ColorStop
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// Where should it be? 0 is at the start, 1 at the end of the Gradient.
+ /// What color should be used at that point?
+ public ColorStop(float ratio, TPixel color)
+ {
+ this.Ratio = ratio;
+ this.Color = color;
+ }
+
+ ///
+ /// Gets the point along the defined gradient axis.
+ ///
+ public float Ratio { get; }
+
+ ///
+ /// Gets the color to be used.
+ ///
+ public TPixel Color { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs
new file mode 100644
index 0000000000..782f5d4d73
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/DrawBezierExtensions.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of Bezier paths to the type.
+ ///
+ public static class DrawBezierExtensions
+ {
+ ///
+ /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The brush.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IBrush brush, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(options, new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points)));
+
+ ///
+ /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The brush.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IBrush brush, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(new Pen(brush, thickness), new Path(new CubicBezierLineSegment(points)));
+
+ ///
+ /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The color.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, TPixel color, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.DrawBeziers(new SolidBrush(color), thickness, points);
+
+ ///
+ /// Draws the provided points as an open Bezier path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The color.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.DrawBeziers(options, new SolidBrush(color), thickness, points);
+
+ ///
+ /// Draws the provided points as an open Bezier path with the supplied pen
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The pen.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, GraphicsOptions options, IPen pen, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(options, pen, new Path(new CubicBezierLineSegment(points)));
+
+ ///
+ /// Draws the provided points as an open Bezier path with the supplied pen
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The pen.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawBeziers(this IImageProcessingContext source, IPen pen, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(pen, new Path(new CubicBezierLineSegment(points)));
+ }
+}
diff --git a/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs
new file mode 100644
index 0000000000..a8ee4d90bc
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs
@@ -0,0 +1,137 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Processors.Drawing;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of images to the type.
+ ///
+ public static class DrawImageExtensions
+ {
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The blending mode.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The color blending mode.
+ /// The alpha composition mode.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, alphaComposition, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The options, including the blending type and blending amount.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, GraphicsOptions options)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The location to draw the blended image.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The location to draw the blended image.
+ /// The color blending to apply.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The location to draw the blended image.
+ /// The color blending to apply.
+ /// The alpha composition mode.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, alphaComposition, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The location to draw the blended image.
+ /// The options containing the blend mode and opacity.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, GraphicsOptions options)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/DrawLineExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawLineExtensions.cs
new file mode 100644
index 0000000000..9084b30efe
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/DrawLineExtensions.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of lines to the type.
+ ///
+ public static class DrawLineExtensions
+ {
+ ///
+ /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The brush.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, GraphicsOptions options, IBrush brush, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(options, new Pen(brush, thickness), new Path(new LinearLineSegment(points)));
+
+ ///
+ /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The brush.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, IBrush brush, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(new Pen(brush, thickness), new Path(new LinearLineSegment(points)));
+
+ ///
+ /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The color.
+ /// The thickness.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, TPixel color, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.DrawLines(new SolidBrush(color), thickness, points);
+
+ ///
+ /// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The color.
+ /// The thickness.
+ /// The points.
+ /// The .>
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, GraphicsOptions options, TPixel color, float thickness, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.DrawLines(options, new SolidBrush(color), thickness, points);
+
+ ///
+ /// Draws the provided Points as an open Linear path with the supplied pen
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The pen.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, GraphicsOptions options, IPen pen, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(options, pen, new Path(new LinearLineSegment(points)));
+
+ ///
+ /// Draws the provided Points as an open Linear path with the supplied pen
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The pen.
+ /// The points.
+ /// The .
+ public static IImageProcessingContext DrawLines(this IImageProcessingContext source, IPen pen, params PointF[] points)
+ where TPixel : struct, IPixel
+ => source.Draw(pen, new Path(new LinearLineSegment(points)));
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/DrawPathCollectionExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawPathCollectionExtensions.cs
new file mode 100644
index 0000000000..0d3abf297e
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/DrawPathCollectionExtensions.cs
@@ -0,0 +1,100 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of collections of polygon outlines to the type.
+ ///
+ public static class DrawPathCollectionExtensions
+ {
+ ///
+ /// Draws the outline of the polygon with the provided pen.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The pen.
+ /// The paths.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, GraphicsOptions options, IPen pen, IPathCollection paths)
+ where TPixel : struct, IPixel
+ {
+ foreach (IPath path in paths)
+ {
+ source.Draw(options, pen, path);
+ }
+
+ return source;
+ }
+
+ ///
+ /// Draws the outline of the polygon with the provided pen.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The pen.
+ /// The paths.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, IPen pen, IPathCollection paths)
+ where TPixel : struct, IPixel
+ => source.Draw(GraphicsOptions.Default, pen, paths);
+
+ ///
+ /// Draws the outline of the polygon with the provided brush at the provided thickness.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The brush.
+ /// The thickness.
+ /// The shapes.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, GraphicsOptions options, IBrush brush, float thickness, IPathCollection paths)
+ where TPixel : struct, IPixel
+ => source.Draw(options, new Pen(brush, thickness), paths);
+
+ ///
+ /// Draws the outline of the polygon with the provided brush at the provided thickness.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The brush.
+ /// The thickness.
+ /// The paths.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, IBrush brush, float thickness, IPathCollection paths)
+ where TPixel : struct, IPixel
+ => source.Draw(new Pen(brush, thickness), paths);
+
+ ///
+ /// Draws the outline of the polygon with the provided brush at the provided thickness.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The color.
+ /// The thickness.
+ /// The paths.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, GraphicsOptions options, TPixel color, float thickness, IPathCollection paths)
+ where TPixel : struct, IPixel
+ => source.Draw(options, new SolidBrush(color), thickness, paths);
+
+ ///
+ /// Draws the outline of the polygon with the provided brush at the provided thickness.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The color.
+ /// The thickness.
+ /// The paths.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, TPixel color, float thickness, IPathCollection paths)
+ where TPixel : struct, IPixel
+ => source.Draw(new SolidBrush(color), thickness, paths);
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/DrawPathExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawPathExtensions.cs
new file mode 100644
index 0000000000..4dbe942f2b
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/DrawPathExtensions.cs
@@ -0,0 +1,94 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Primitives;
+using SixLabors.Shapes;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of polygon outlines to the type.
+ ///
+ public static class DrawPathExtensions
+ {
+ ///
+ /// Draws the outline of the polygon with the provided pen.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The options.
+ /// The pen.
+ /// The path.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, GraphicsOptions options, IPen pen, IPath path)
+ where TPixel : struct, IPixel
+ => source.Fill(options, pen.StrokeFill, new ShapePath(path, pen));
+
+ ///
+ /// Draws the outline of the polygon with the provided pen.
+ ///
+ /// The type of the color.
+ /// The image this method extends.
+ /// The pen.
+ /// The path.
+ /// The .
+ public static IImageProcessingContext Draw(this IImageProcessingContext source, IPen pen, IPath path)
+ where TPixel : struct, IPixel
+ => source.Draw(GraphicsOptions.Default, pen, path);
+
+ ///