diff --git a/.azuredevops/Pipelines/build.yaml b/.azuredevops/Pipelines/build.yaml index d67a1ad..4d217a3 100644 --- a/.azuredevops/Pipelines/build.yaml +++ b/.azuredevops/Pipelines/build.yaml @@ -45,12 +45,6 @@ stages: - script: git submodule update --init --recursive displayName: Update git submodules - - task: UseDotNet@2 - displayName: "Use dotnet sdk 2.1.x" - inputs: - version: 2.1.x - includePreviewVersions: false - - task: UseDotNet@2 displayName: "Use dotnet sdk 3.1.x" inputs: @@ -67,7 +61,7 @@ stages: displayName: "Use dotnet sdk 6.0.x" inputs: version: 6.0.x - includePreviewVersions: true + includePreviewVersions: false - script: dotnet --info displayName: Show dotnet SDK info diff --git a/.azuredevops/Pipelines/pull-request.yaml b/.azuredevops/Pipelines/pull-request.yaml index bf32ce4..d8bc33c 100644 --- a/.azuredevops/Pipelines/pull-request.yaml +++ b/.azuredevops/Pipelines/pull-request.yaml @@ -30,12 +30,6 @@ stages: value: 39ce9363-a308-4580-8610-ee11f4953539/01001223-8651-4b73-a7ca-ba27c3e10a3c steps: - - task: UseDotNet@2 - displayName: "Use dotnet sdk 2.1.x" - inputs: - version: 2.1.x - includePreviewVersions: false - - task: UseDotNet@2 displayName: "Use dotnet sdk 3.1.x" inputs: @@ -52,7 +46,7 @@ stages: displayName: "Use dotnet sdk 6.0.x" inputs: version: 6.0.x - includePreviewVersions: true + includePreviewVersions: false - script: dotnet --info displayName: Show dotnet SDK info diff --git a/.github/workflows/on-push-do-test.yml b/.github/workflows/on-push-do-test.yml index 79a0985..0a38b64 100644 --- a/.github/workflows/on-push-do-test.yml +++ b/.github/workflows/on-push-do-test.yml @@ -20,11 +20,6 @@ jobs: with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 2.1.x - - name: Setup .NET uses: actions/setup-dotnet@v1 with: @@ -39,7 +34,7 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: 6.0.x - include-prerelease: true + include-prerelease: false - name: Remove demo project from solution run: dotnet sln ImageHash.sln remove demo/Demo.csproj diff --git a/Directory.Build.props b/Directory.Build.props index 8d6b68c..ab33013 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,6 +5,6 @@ - false + \ No newline at end of file diff --git a/ImageHash.sln b/ImageHash.sln index f1fe160..5e3aa7f 100644 --- a/ImageHash.sln +++ b/ImageHash.sln @@ -14,7 +14,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig Directory.Build.props = Directory.Build.props Directory.Build.targets = Directory.Build.targets - GitVersion.yml = GitVersion.yml build\Packages.targets = build\Packages.targets README.md = README.md version.json = version.json diff --git a/build/Packages.targets b/build/Packages.targets index 26dbbce..5ebe8d5 100644 --- a/build/Packages.targets +++ b/build/Packages.targets @@ -14,8 +14,8 @@ - - + + diff --git a/src/ImageHash/HashAlgorithms/AverageHash.cs b/src/ImageHash/HashAlgorithms/AverageHash.cs index 5601650..297c46c 100644 --- a/src/ImageHash/HashAlgorithms/AverageHash.cs +++ b/src/ImageHash/HashAlgorithms/AverageHash.cs @@ -35,40 +35,43 @@ public ulong Hash(Image image) .Grayscale(GrayscaleMode.Bt601) .AutoOrient()); - uint averageValue = 0; + var hash = 0UL; - for (var y = 0; y < HEIGHT; y++) - { - Span row = image.GetPixelRowSpan(y); - for (var x = 0; x < WIDTH; x++) + image.ProcessPixelRows((imageAccessor) => { - // We know 4 bytes (RGBA) are used to describe one pixel - // Also, it is already grayscaled, so R=G=B. Therefore, we can take one of these - // values for average calculation. We take the R (the first of each 4 bytes). - averageValue += row[x].R; - } - } + uint averageValue = 0; + for (var y = 0; y < HEIGHT; y++) + { + Span row = imageAccessor.GetRowSpan(y); + for (var x = 0; x < WIDTH; x++) + { + // We know 4 bytes (RGBA) are used to describe one pixel + // Also, it is already grayscaled, so R=G=B. Therefore, we can take one of these + // values for average calculation. We take the R (the first of each 4 bytes). + averageValue += row[x].R; + } + } - averageValue /= NR_PIXELS; + averageValue /= NR_PIXELS; - // Compute the hash: each bit is a pixel - // 1 = higher than average, 0 = lower than average - var hash = 0UL; - var mask = MOST_SIGNIFICANT_BIT_MASK; + // Compute the hash: each bit is a pixel + // 1 = higher than average, 0 = lower than average + var mask = MOST_SIGNIFICANT_BIT_MASK; - for (var y = 0; y < HEIGHT; y++) - { - Span row = image.GetPixelRowSpan(y); - for (var x = 0; x < WIDTH; x++) - { - if (row[x].R >= averageValue) + for (var y = 0; y < HEIGHT; y++) { - hash |= mask; - } + Span row = imageAccessor.GetRowSpan(y); + for (var x = 0; x < WIDTH; x++) + { + if (row[x].R >= averageValue) + { + hash |= mask; + } - mask >>= 1; - } - } + mask >>= 1; + } + } + }); return hash; } diff --git a/src/ImageHash/HashAlgorithms/DifferenceHash.cs b/src/ImageHash/HashAlgorithms/DifferenceHash.cs index d21f2e7..b58cf7f 100644 --- a/src/ImageHash/HashAlgorithms/DifferenceHash.cs +++ b/src/ImageHash/HashAlgorithms/DifferenceHash.cs @@ -34,26 +34,30 @@ public ulong Hash(Image image) .Resize(WIDTH, HEIGHT) .Grayscale(GrayscaleMode.Bt601)); - var mask = 1UL << ((HEIGHT * (WIDTH - 1)) - 1); var hash = 0UL; - for (var y = 0; y < HEIGHT; y++) - { - Span row = image.GetPixelRowSpan(y); - Rgba32 leftPixel = row[0]; - - for (var index = 1; index < WIDTH; index++) + image.ProcessPixelRows((imageAccessor) => { - Rgba32 rightPixel = row[index]; - if (leftPixel.R < rightPixel.R) + var mask = 1UL << ((HEIGHT * (WIDTH - 1)) - 1); + + for (var y = 0; y < HEIGHT; y++) { - hash |= mask; - } + Span row = imageAccessor.GetRowSpan(y); + Rgba32 leftPixel = row[0]; - leftPixel = rightPixel; - mask >>= 1; - } - } + for (var index = 1; index < WIDTH; index++) + { + Rgba32 rightPixel = row[index]; + if (leftPixel.R < rightPixel.R) + { + hash |= mask; + } + + leftPixel = rightPixel; + mask >>= 1; + } + } + }); return hash; } diff --git a/src/ImageHash/HashAlgorithms/PerceptualHash.cs b/src/ImageHash/HashAlgorithms/PerceptualHash.cs index 4eccbca..49b69e9 100644 --- a/src/ImageHash/HashAlgorithms/PerceptualHash.cs +++ b/src/ImageHash/HashAlgorithms/PerceptualHash.cs @@ -98,7 +98,7 @@ private static double CalculateMedian64Values(IReadOnlyCollection values private static List>[] GenerateDctCoeffsSimd() { - List>[] results = new List>[SIZE]; + var results = new List>[SIZE]; for (var coef = 0; coef < SIZE; coef++) { var singleResultRaw = new double[SIZE]; @@ -110,7 +110,7 @@ private static List>[] GenerateDctCoeffsSimd() var singleResultList = new List>(); var stride = Vector.Count; Debug.Assert(SIZE % stride == 0, "Size must be a multiple of SIMD stride"); - for (int i = 0; i < SIZE; i += stride) + for (var i = 0; i < SIZE; i += stride) { var v = new Vector(singleResultRaw, i); singleResultList.Add(v); @@ -136,14 +136,14 @@ private static void Dct1D_SIMD(double[] valuesRaw, double[,] coefficients, int c var valuesList = new List>(); var stride = Vector.Count; - for (int i = 0; i < valuesRaw.Length; i += stride) + for (var i = 0; i < valuesRaw.Length; i += stride) { valuesList.Add(new Vector(valuesRaw, i)); } for (var coef = 0; coef < limit; coef++) { - for (int i = 0; i < valuesList.Count; i++) + for (var i = 0; i < valuesList.Count; i++) { coefficients[ci, coef] += Vector.Dot(valuesList[i], _dctCoeffsSimd[coef][i]); } diff --git a/src/ImageHash/ImageHash.csproj b/src/ImageHash/ImageHash.csproj index cc6395d..33e286a 100644 --- a/src/ImageHash/ImageHash.csproj +++ b/src/ImageHash/ImageHash.csproj @@ -1,6 +1,6 @@  - netstandard1.3;netstandard2.0;netcoreapp2.1;netcoreapp3.1;net5;net6 + netstandard2.0;netcoreapp2.1;netcoreapp3.1;net5;net6 $(TargetFrameworks);net461;net472 Perceptual image hashing in netstandard using the ImageSharp library. Includes three hashing algorithms (AverageHash, DifferenceHash, and PerceptualHash). CoenM.ImageHash diff --git a/tests/ImageHash.Test/ImageHash.Test.csproj b/tests/ImageHash.Test/ImageHash.Test.csproj index 655c5fb..be34a7c 100644 --- a/tests/ImageHash.Test/ImageHash.Test.csproj +++ b/tests/ImageHash.Test/ImageHash.Test.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1;net5;net6 + netcoreapp3.1;net5;net6 $(TargetFrameworks);net461;net472 false CoenM.ImageSharp.ImageHash.Test