Initial commit
This commit is contained in:
commit
8a9217aede
19 changed files with 382 additions and 0 deletions
116
.gitignore
vendored
Normal file
116
.gitignore
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/rider,windows
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=rider,windows
|
||||
|
||||
### Rider ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/rider,windows
|
13
.idea/.idea.ImgMetadataRemover/.idea/.gitignore
vendored
Normal file
13
.idea/.idea.ImgMetadataRemover/.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/projectSettingsUpdater.xml
|
||||
/contentModel.xml
|
||||
/modules.xml
|
||||
/.idea.ImgMetadataRemover.iml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
4
.idea/.idea.ImgMetadataRemover/.idea/encodings.xml
Normal file
4
.idea/.idea.ImgMetadataRemover/.idea/encodings.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
8
.idea/.idea.ImgMetadataRemover/.idea/indexLayout.xml
Normal file
8
.idea/.idea.ImgMetadataRemover/.idea/indexLayout.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
6
.idea/.idea.ImgMetadataRemover/.idea/vcs.xml
Normal file
6
.idea/.idea.ImgMetadataRemover/.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
14
ConsoleInterface/ConsoleInterface.csproj
Normal file
14
ConsoleInterface/ConsoleInterface.csproj
Normal file
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Image\Image.csproj"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
23
ConsoleInterface/Program.cs
Normal file
23
ConsoleInterface/Program.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using Image;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ConsoleInterface
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var loggerFactory = LoggerFactory.Create(b => b.AddConsole());
|
||||
var outputFormatter = OriginalFilenameOutputFormatter.Create(@"C:\Users\nutiu\Downloads\Photos-001\clean");
|
||||
var executor = TasksExecutor.Create();
|
||||
executor.Logger = loggerFactory.CreateLogger("Executor");
|
||||
executor.ParallelCleanImages(new[]
|
||||
{
|
||||
@"C:\Users\nutiu\Downloads\Photos-001\IMG_0138.HEIC",
|
||||
@"C:\Users\nutiu\Downloads\Photos-001\IMG_0137.HEIC",
|
||||
@"C:\Users\nutiu\Downloads\Photos-001\IMG_0140.HEIC",
|
||||
@"C:\Users\nutiu\Downloads\Photos-001\12382975864_09e6e069e7_o.jpg"
|
||||
}, outputFormatter);
|
||||
}
|
||||
}
|
||||
}
|
38
Image/Cleaner.cs
Normal file
38
Image/Cleaner.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
using ImageMagick;
|
||||
|
||||
namespace Image
|
||||
{
|
||||
public class Cleaner : ICleaner
|
||||
{
|
||||
private readonly ICompressor _compressor;
|
||||
private readonly IMagickImage _magickImage;
|
||||
|
||||
public Cleaner(IMagickImage magickImage, ICompressor compressor)
|
||||
{
|
||||
_magickImage = magickImage;
|
||||
_compressor = compressor;
|
||||
}
|
||||
|
||||
public Cleaner(string fileName) : this(new MagickImage(fileName), new LosslessCompressor())
|
||||
{
|
||||
}
|
||||
|
||||
public void CleanImage(string newFileName)
|
||||
{
|
||||
_magickImage.RemoveProfile("exif");
|
||||
_magickImage.Write(newFileName);
|
||||
_compressor.Compress(newFileName);
|
||||
}
|
||||
|
||||
public void RemoveExifData(string newFilename)
|
||||
{
|
||||
_magickImage.RemoveProfile("exif");
|
||||
_magickImage.Write(newFilename);
|
||||
}
|
||||
|
||||
public void OptimizeImage(string fileName)
|
||||
{
|
||||
_compressor.Compress(fileName);
|
||||
}
|
||||
}
|
||||
}
|
9
Image/ICleaner.cs
Normal file
9
Image/ICleaner.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace Image
|
||||
{
|
||||
public interface ICleaner
|
||||
{
|
||||
void CleanImage(string newFileName);
|
||||
void OptimizeImage(string fileName);
|
||||
public void RemoveExifData(string newFilename);
|
||||
}
|
||||
}
|
7
Image/ICompressor.cs
Normal file
7
Image/ICompressor.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Image
|
||||
{
|
||||
public interface ICompressor
|
||||
{
|
||||
public void Compress(string fileName);
|
||||
}
|
||||
}
|
7
Image/IOutputFormatter.cs
Normal file
7
Image/IOutputFormatter.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Image
|
||||
{
|
||||
public interface IOutputFormatter
|
||||
{
|
||||
string FormatOutputPath(string filePath);
|
||||
}
|
||||
}
|
14
Image/Image.csproj
Normal file
14
Image/Image.csproj
Normal file
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Image</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="8.6.1"/>
|
||||
<PackageReference Include="Magick.NET.Core" Version="8.6.1"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
19
Image/LosslessCompressor.cs
Normal file
19
Image/LosslessCompressor.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using ImageMagick;
|
||||
|
||||
namespace Image
|
||||
{
|
||||
public class LosslessCompressor : ICompressor
|
||||
{
|
||||
private readonly ImageOptimizer _imageOptimizer;
|
||||
|
||||
public LosslessCompressor()
|
||||
{
|
||||
_imageOptimizer = new ImageOptimizer();
|
||||
}
|
||||
|
||||
public void Compress(string fileName)
|
||||
{
|
||||
_imageOptimizer.LosslessCompress(fileName);
|
||||
}
|
||||
}
|
||||
}
|
27
Image/OriginalFilenameOutputFormatter.cs
Normal file
27
Image/OriginalFilenameOutputFormatter.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System.IO;
|
||||
|
||||
namespace Image
|
||||
{
|
||||
public class OriginalFilenameOutputFormatter : IOutputFormatter
|
||||
{
|
||||
private readonly string _rootDirectory;
|
||||
|
||||
public OriginalFilenameOutputFormatter(string rootDirectory)
|
||||
{
|
||||
if (!Directory.Exists(rootDirectory)) Directory.CreateDirectory(rootDirectory);
|
||||
_rootDirectory = rootDirectory;
|
||||
}
|
||||
|
||||
public string FormatOutputPath(string filePath)
|
||||
{
|
||||
var fileName = Path.GetFileName(filePath);
|
||||
var path = Path.Join(_rootDirectory, $"{fileName}.jpg");
|
||||
return path;
|
||||
}
|
||||
|
||||
public static OriginalFilenameOutputFormatter Create(string rootDirectory)
|
||||
{
|
||||
return new OriginalFilenameOutputFormatter(rootDirectory);
|
||||
}
|
||||
}
|
||||
}
|
43
Image/TasksExecutor.cs
Normal file
43
Image/TasksExecutor.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace Image
|
||||
{
|
||||
public class TasksExecutor
|
||||
{
|
||||
public ILogger Logger = NullLogger.Instance;
|
||||
|
||||
public static TasksExecutor Create()
|
||||
{
|
||||
return new TasksExecutor();
|
||||
}
|
||||
|
||||
public void CleanImage(string fileName, string newFilename)
|
||||
{
|
||||
ICleaner cleaner = new Cleaner(fileName);
|
||||
cleaner.CleanImage(newFilename);
|
||||
}
|
||||
|
||||
public void ParallelCleanImages(IEnumerable<string> fileNames, IOutputFormatter outputFormatter)
|
||||
{
|
||||
Logger.LogInformation("Starting parallel image cleaning.");
|
||||
var tasks = new List<Task>();
|
||||
foreach (var fileName in fileNames)
|
||||
{
|
||||
var task = new Task(() => { CleanImage(fileName, outputFormatter.FormatOutputPath(fileName)); });
|
||||
tasks.Add(task);
|
||||
task.Start();
|
||||
}
|
||||
|
||||
var result = Task.WhenAll(tasks);
|
||||
result.Wait();
|
||||
|
||||
var successTasks = tasks.Count(t => t.IsCompletedSuccessfully);
|
||||
var errorTasks = tasks.Count() - successTasks;
|
||||
Logger.LogInformation($"All tasks completed. Success: {successTasks}, Errors: {errorTasks}");
|
||||
}
|
||||
}
|
||||
}
|
22
ImgMetadataRemover.sln
Normal file
22
ImgMetadataRemover.sln
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Image", "Image\Image.csproj", "{10AD7910-C8AA-43ED-9231-EBE267AC270F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleInterface", "ConsoleInterface\ConsoleInterface.csproj", "{F04E0337-23D3-4209-9BDE-B798090A7A63}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{10AD7910-C8AA-43ED-9231-EBE267AC270F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{10AD7910-C8AA-43ED-9231-EBE267AC270F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{10AD7910-C8AA-43ED-9231-EBE267AC270F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{10AD7910-C8AA-43ED-9231-EBE267AC270F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F04E0337-23D3-4209-9BDE-B798090A7A63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F04E0337-23D3-4209-9BDE-B798090A7A63}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F04E0337-23D3-4209-9BDE-B798090A7A63}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F04E0337-23D3-4209-9BDE-B798090A7A63}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
5
ImgMetadataRemover.sln.DotSettings.user
Normal file
5
ImgMetadataRemover.sln.DotSettings.user
Normal file
|
@ -0,0 +1,5 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||
<Assembly Path="C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Net.Mail.dll" />
|
||||
<Assembly Path="C:\Users\nutiu\.nuget\packages\magick.net.core\8.6.1\lib\netstandard21\Magick.NET.Core.dll" />
|
||||
</AssemblyExplorer></s:String></wpf:ResourceDictionary>
|
BIN
README.md
Normal file
BIN
README.md
Normal file
Binary file not shown.
7
global.json
Normal file
7
global.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "3.1",
|
||||
"rollForward": "latestMajor",
|
||||
"allowPrerelease": false
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue