Added Sample console application (#676)

* Added SvgConsole application
* Added input directory support
* Added multiple output files support
* Added Log and Error methods
* Updated README.md
This commit is contained in:
Wiesław Šoltés 2020-02-21 19:16:14 +01:00 коммит произвёл GitHub
Родитель d577f447bc
Коммит b84f28b007
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 328 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,205 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using System.Threading.Tasks;
using Svg;
namespace SvgConsole
{
class Settings
{
public FileInfo[] InputFiles { get; set; }
public DirectoryInfo InputDirectory { get; set; }
public FileInfo[] OutputFiles { get; set; }
public DirectoryInfo OutputDirectory { get; set; }
public float? Width { get; set; }
public float? Height { get; set; }
}
class Program
{
static void Log(string message)
{
Console.WriteLine(message);
}
static void Error(Exception ex)
{
Log($"{ex.Message}");
Log($"{ex.StackTrace}");
if (ex.InnerException != null)
{
Error(ex.InnerException);
}
}
static void GetFiles(DirectoryInfo directory, string pattern, List<FileInfo> paths)
{
var files = Directory.EnumerateFiles(directory.FullName, pattern);
if (files != null)
{
foreach (var path in files)
{
paths.Add(new FileInfo(path));
}
}
}
static void Save(FileInfo inputPath, string outputPath, float? width, float? height)
{
var svgDocument = SvgDocument.Open(inputPath.FullName);
if (svgDocument == null)
{
Log($"Error: Failed to load input file: {inputPath.FullName}");
return;
}
if (width.HasValue)
{
svgDocument.Width = width.Value;
}
if (height.HasValue)
{
svgDocument.Height = height.Value;
}
using (var bitmap = svgDocument.Draw())
{
bitmap.Save(outputPath);
}
}
static void Run(Settings settings)
{
var paths = new List<FileInfo>();
if (settings.InputFiles != null)
{
foreach (var file in settings.InputFiles)
{
paths.Add(file);
}
}
if (settings.InputDirectory != null)
{
var directory = settings.InputDirectory;
GetFiles(directory, "*.svg", paths);
GetFiles(directory, "*.svgz", paths);
}
if (settings.OutputDirectory != null && !string.IsNullOrEmpty(settings.OutputDirectory.FullName))
{
if (!Directory.Exists(settings.OutputDirectory.FullName))
{
Directory.CreateDirectory(settings.OutputDirectory.FullName);
}
}
if (settings.OutputFiles != null)
{
if (paths.Count > 0 && paths.Count != settings.OutputFiles.Length)
{
Log($"Error: The number of the output files must match the number of the input files.");
return;
}
}
for (int i = 0; i < paths.Count; i++)
{
var inputPath = paths[i];
var outputFile = settings.OutputFiles != null ? settings.OutputFiles[i] : null;
try
{
var outputPath = string.Empty;
if (outputFile != null)
{
outputPath = outputFile.FullName;
}
else
{
var inputExtension = inputPath.Extension;
outputPath = Path.ChangeExtension(inputPath.FullName, ".png");
if (settings.OutputDirectory != null && !string.IsNullOrEmpty(settings.OutputDirectory.FullName))
{
outputPath = Path.Combine(settings.OutputDirectory.FullName, Path.GetFileName(outputPath));
}
}
Directory.SetCurrentDirectory(Path.GetDirectoryName(inputPath.FullName));
Save(inputPath, outputPath, settings.Width, settings.Height);
}
catch (Exception ex)
{
Log($"Error: {inputPath.FullName}");
Error(ex);
}
}
}
static async Task<int> Main(string[] args)
{
var optionInputFiles = new Option(new[] { "--inputFiles", "-f" }, "The relative or absolute path to the input files")
{
Argument = new Argument<FileInfo[]>(getDefaultValue: () => null)
};
var optionInputDirectory = new Option(new[] { "--inputDirectory", "-d" }, "The relative or absolute path to the input directory")
{
Argument = new Argument<DirectoryInfo>(getDefaultValue: () => null)
};
var optionOutputDirectory = new Option(new[] { "--outputDirectory", "-o" }, "The relative or absolute path to the output directory")
{
Argument = new Argument<DirectoryInfo>(getDefaultValue: () => null)
};
var optionOutputFiles = new Option(new[] { "--outputFiles" }, "The relative or absolute path to the output files")
{
Argument = new Argument<FileInfo[]>(getDefaultValue: () => null)
};
var optionWidth = new Option(new[] { "--width" }, "The output image width override")
{
Argument = new Argument<float?>(getDefaultValue: () => null)
};
var optionHeight = new Option(new[] { "--height" }, "The output image height override")
{
Argument = new Argument<float?>(getDefaultValue: () => null)
};
var rootCommand = new RootCommand()
{
Description = "Converts svg files to encoded png images."
};
rootCommand.AddOption(optionInputFiles);
rootCommand.AddOption(optionInputDirectory);
rootCommand.AddOption(optionOutputDirectory);
rootCommand.AddOption(optionOutputFiles);
rootCommand.AddOption(optionWidth);
rootCommand.AddOption(optionHeight);
rootCommand.Handler = CommandHandler.Create((Settings settings) =>
{
try
{
Run(settings);
}
catch (Exception ex)
{
Error(ex);
}
});
return await rootCommand.InvokeAsync(args);
}
}
}

Просмотреть файл

@ -0,0 +1,76 @@
# SvgConsole
## .NET Core
Install latest [.NET Core SDK](https://dotnet.microsoft.com/download).
## Publish
### Windows
```
cd Samples/SvgConsole
dotnet publish -f netcoreapp2.2 -c Release -r win-x64 -o SvgConsole-win-x64-netcoreapp2.2
cd SvgConsole-win-x64-netcoreapp2.2
```
### Linux
```
cd Samples/SvgConsole
dotnet publish -f netcoreapp2.2 -c Release -r linux-x64 -o SvgConsole-linux-x64-netcoreapp2.2
cd SvgConsole-linux-x64-netcoreapp2.2
```
### macOS
```
cd Samples/SvgConsole
dotnet publish -f netcoreapp2.2 -c Release -r osx-x64 -o SvgConsole-osx-x64-netcoreapp2.2
cd SvgConsole-osx-x64-netcoreapp2.2
```
### Other
* [.NET Core RID Catalog](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog)
* [dotnet publish](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish)
## Usage
```
SvgConsole:
Converts svg files to encoded png images.
Usage:
SvgConsole [options]
Options:
-f, --inputFiles <inputfiles> The relative or absolute path to the input files
-d, --inputDirectory <inputdirectory> The relative or absolute path to the input directory
-o, --outputDirectory <outputdirectory> The relative or absolute path to the output directory
--outputFiles <outputfiles> The relative or absolute path to the output files
--width <width> The output image width override
--height <height> The output image height override
--version Show version information
-?, -h, --help Show help and usage information
```
```
./SvgConsole -f ~/svg/Example.svg
```
```
./SvgConsole -f ~/svg/Example.svg --outputFiles ~/png/Example.png
```
```
./SvgConsole -f ~/svg/Example.svg -o ~/png
```
```
./SvgConsole -d ~/svg/
```
```
./SvgConsole -d ~/svg -o ~/png
```

Просмотреть файл

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>False</IsPackable>
<IsTool>True</IsTool>
<PackAsTool>True</PackAsTool>
<ToolCommandName>SvgConsole</ToolCommandName>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup>
<PublishTrimmed>True</PublishTrimmed>
<PublishReadyToRun>True</PublishReadyToRun>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Source\Svg.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20104.2" />
</ItemGroup>
</Project>

Просмотреть файл

@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XMLOutputTester", "..\Sampl
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{2EC3F3A0-F097-43EF-A603-9B82E3061469}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SvgConsole", "..\Samples\SvgConsole\SvgConsole.csproj", "{9379360C-CB0B-4035-AE8F-8863A420FDCF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -111,6 +113,18 @@ Global
{8CEEB917-63E2-4AE7-B0D1-50A840050975}.Release|Mixed Platforms.Build.0 = Release|x86
{8CEEB917-63E2-4AE7-B0D1-50A840050975}.Release|x86.ActiveCfg = Release|x86
{8CEEB917-63E2-4AE7-B0D1-50A840050975}.Release|x86.Build.0 = Release|x86
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|x86.ActiveCfg = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Debug|x86.Build.0 = Debug|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|Any CPU.Build.0 = Release|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|x86.ActiveCfg = Release|Any CPU
{9379360C-CB0B-4035-AE8F-8863A420FDCF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -122,6 +136,7 @@ Global
{9782B15C-D0BA-4A4E-9A03-F97082AF9256} = {038E2E7B-BC03-4DA7-AA5F-CA8BD95BD0F2}
{F34CF345-E7EF-4354-B49A-AFE7A78442A7} = {038E2E7B-BC03-4DA7-AA5F-CA8BD95BD0F2}
{8CEEB917-63E2-4AE7-B0D1-50A840050975} = {038E2E7B-BC03-4DA7-AA5F-CA8BD95BD0F2}
{9379360C-CB0B-4035-AE8F-8863A420FDCF} = {038E2E7B-BC03-4DA7-AA5F-CA8BD95BD0F2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5096EEB3-8F41-44B5-BCF9-58743A59AB21}

Просмотреть файл

@ -8,6 +8,7 @@ environment:
before_build:
- ps: nuget restore Source\Svg.csproj
- ps: nuget restore Samples\SvgConsole\SvgConsole.csproj
- ps: nuget restore Tests\Svg.UnitTests\Svg.UnitTests.csproj
- ps: nuget install NUnit.ConsoleRunner -Version 3.10.0 -OutputDirectory tools
- ps: |

Просмотреть файл

@ -31,6 +31,10 @@ Entities
Another small command line application that loads an example file that references entities not present
in the file, and provides these entities with matching styles dynamically in the `SvgDocument.Open` call.
SvgConsole
----------
This is a simple command-line application to convert one or many input SVG files to PNG images. It shows how to open a SVG document and create bitmap, and how to save resulting bitmap to a PNG file.
---
As you can see, there are currently very few code samples. We encourage you to add your own sample code
in pull requests, or provide code snippets that can be made into samples.