diff --git a/.gitignore b/.gitignore
index 3e759b75bf45..1e3f70137ce8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -301,6 +301,8 @@ __pycache__/
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
+ImageResizer/tools/**
+!ImageResizer/tools/packages.config
# Tabs Studio
*.tss
diff --git a/ImageResizer/ImageResizer.sln b/ImageResizer/ImageResizer.sln
new file mode 100644
index 000000000000..b0cbb7839ca0
--- /dev/null
+++ b/ImageResizer/ImageResizer.sln
@@ -0,0 +1,85 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2036
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A7268E69-B2B8-4B0D-A47A-CB2AFC705D43}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageResizer", "src\ImageResizer\ImageResizer.csproj", "{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShellExtensions", "src\ShellExtensions\ShellExtensions.vcxproj", "{0B43679E-EDFA-4DA0-AD30-F4628B308B1B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{03474E84-5425-4E89-9056-AFF15EA7DE57}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageResizer.Test", "test\ImageResizer.Test\ImageResizer.Test.csproj", "{E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "setup", "setup", "{8E477B70-095E-4C84-BE9B-B347C11688F7}"
+EndProject
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Msi", "setup\Msi\Msi.wixproj", "{C6FF3D16-7935-4100-9CA1-2A45A3F7A058}"
+EndProject
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "X64Msi", "setup\X64Msi\X64Msi.wixproj", "{EA394F60-7616-4DDB-9F45-60F585460364}"
+EndProject
+Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Bundle", "setup\Bundle\Bundle.wixproj", "{E75AE740-CE28-40D1-BCFA-547A30EDBF09}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Debug|x86.Build.0 = Debug|Any CPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x64.ActiveCfg = Release|Any CPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x86.ActiveCfg = Release|Any CPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}.Release|x86.Build.0 = Release|Any CPU
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.ActiveCfg = Debug|x64
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x64.Build.0 = Debug|x64
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x86.ActiveCfg = Debug|Win32
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Debug|x86.Build.0 = Debug|Win32
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.ActiveCfg = Release|x64
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x64.Build.0 = Release|x64
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x86.ActiveCfg = Release|Win32
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}.Release|x86.Build.0 = Release|Win32
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Debug|x86.Build.0 = Debug|Any CPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x64.ActiveCfg = Release|Any CPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x86.ActiveCfg = Release|Any CPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}.Release|x86.Build.0 = Release|Any CPU
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Debug|x64.ActiveCfg = Debug|x86
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Debug|x86.ActiveCfg = Debug|x86
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Debug|x86.Build.0 = Debug|x86
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Release|x64.ActiveCfg = Release|x86
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Release|x86.ActiveCfg = Release|x86
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058}.Release|x86.Build.0 = Release|x86
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Debug|x64.ActiveCfg = Debug|x64
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Debug|x64.Build.0 = Debug|x64
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Debug|x86.ActiveCfg = Debug|x64
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Release|x64.ActiveCfg = Release|x64
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Release|x64.Build.0 = Release|x64
+ {EA394F60-7616-4DDB-9F45-60F585460364}.Release|x86.ActiveCfg = Release|x64
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Debug|x64.ActiveCfg = Debug|x86
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Debug|x86.ActiveCfg = Debug|x86
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Debug|x86.Build.0 = Debug|x86
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Release|x64.ActiveCfg = Release|x86
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Release|x86.ActiveCfg = Release|x86
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34} = {A7268E69-B2B8-4B0D-A47A-CB2AFC705D43}
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B} = {A7268E69-B2B8-4B0D-A47A-CB2AFC705D43}
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8} = {03474E84-5425-4E89-9056-AFF15EA7DE57}
+ {C6FF3D16-7935-4100-9CA1-2A45A3F7A058} = {8E477B70-095E-4C84-BE9B-B347C11688F7}
+ {EA394F60-7616-4DDB-9F45-60F585460364} = {8E477B70-095E-4C84-BE9B-B347C11688F7}
+ {E75AE740-CE28-40D1-BCFA-547A30EDBF09} = {8E477B70-095E-4C84-BE9B-B347C11688F7}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {E0CD6FB1-435F-49A6-AAA0-D1E14A8BB64D}
+ EndGlobalSection
+EndGlobal
diff --git a/ImageResizer/LICENSE b/ImageResizer/LICENSE
new file mode 100644
index 000000000000..02982321bb23
--- /dev/null
+++ b/ImageResizer/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Brice Lambson. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/ImageResizer/NuGet.Config b/ImageResizer/NuGet.Config
new file mode 100644
index 000000000000..4d736c19ec5f
--- /dev/null
+++ b/ImageResizer/NuGet.Config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ImageResizer/build.cake b/ImageResizer/build.cake
new file mode 100644
index 000000000000..3902bf80f744
--- /dev/null
+++ b/ImageResizer/build.cake
@@ -0,0 +1,60 @@
+#tool nuget:?package=xunit.runner.console&version=2.4.1
+
+var target = Argument("target");
+var configuration = Argument("configuration");
+
+var platforms = new[] { "x64", "x86" };
+
+Task("Restore")
+ .Does(
+ () =>
+ NuGetRestore("ImageResizer.sln"));
+
+Task("Build")
+ .IsDependentOn("Restore")
+ .Does(
+ () =>
+ {
+ foreach (var platform in platforms)
+ {
+ MSBuild(
+ "ImageResizer.sln",
+ new MSBuildSettings
+ {
+ ArgumentCustomization = args => args.Append("/nologo")
+ }
+ .SetConfiguration(configuration)
+ .SetMaxCpuCount(0)
+ .SetVerbosity(Verbosity.Minimal)
+ .WithProperty("Platform", platform));
+ }
+ });
+
+Task("Clean")
+ .Does(
+ () =>
+ {
+ foreach (var platform in platforms)
+ {
+ MSBuild(
+ "ImageResizer.sln",
+ new MSBuildSettings()
+ .SetConfiguration(configuration)
+ .WithProperty("Platform", platform)
+ .WithTarget("Clean"));
+ }
+ });
+
+Task("Test")
+ .IsDependentOn("Build")
+ .Does(
+ () =>
+ XUnit2(
+ "./test/ImageResizer.Test/bin/" + configuration + "/ImageResizer.Test.dll",
+ new XUnit2Settings
+ {
+ NoAppDomain = true,
+ ArgumentCustomization = args => args.Append("-nologo")
+ }));
+
+RunTarget(target);
diff --git a/ImageResizer/build.cmd b/ImageResizer/build.cmd
new file mode 100644
index 000000000000..0eb4fed1618f
--- /dev/null
+++ b/ImageResizer/build.cmd
@@ -0,0 +1 @@
+@powershell.exe -File build.ps1 %*
diff --git a/ImageResizer/build.ps1 b/ImageResizer/build.ps1
new file mode 100644
index 000000000000..ca66c2889c7b
--- /dev/null
+++ b/ImageResizer/build.ps1
@@ -0,0 +1,235 @@
+##########################################################################
+# This is the Cake bootstrapper script for PowerShell.
+# This file was downloaded from https://github.com/cake-build/resources
+# Feel free to change this file to fit your needs.
+##########################################################################
+
+<#
+
+.SYNOPSIS
+This is a Powershell script to bootstrap a Cake build.
+
+.DESCRIPTION
+This Powershell script will download NuGet if missing, restore NuGet tools (including Cake)
+and execute your Cake build script with the parameters you provide.
+
+.PARAMETER Script
+The build script to execute.
+.PARAMETER Target
+The build script target to run.
+.PARAMETER Configuration
+The build configuration to use.
+.PARAMETER Verbosity
+Specifies the amount of information to be displayed.
+.PARAMETER ShowDescription
+Shows description about tasks.
+.PARAMETER DryRun
+Performs a dry run.
+.PARAMETER Experimental
+Uses the nightly builds of the Roslyn script engine.
+.PARAMETER Mono
+Uses the Mono Compiler rather than the Roslyn script engine.
+.PARAMETER SkipToolPackageRestore
+Skips restoring of packages.
+.PARAMETER ScriptArgs
+Remaining arguments are added here.
+
+.LINK
+https://cakebuild.net
+
+#>
+
+[CmdletBinding()]
+Param(
+ [string]$Script = "build.cake",
+ [string]$Target = "Test",
+ [string]$Configuration = "Release",
+ [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
+ [string]$Verbosity = "Normal",
+ [switch]$ShowDescription,
+ [Alias("WhatIf", "Noop")]
+ [switch]$DryRun,
+ [switch]$Experimental,
+ [switch]$Mono,
+ [switch]$SkipToolPackageRestore,
+ [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+ [string[]]$ScriptArgs
+)
+
+[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
+function MD5HashFile([string] $filePath)
+{
+ if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf))
+ {
+ return $null
+ }
+
+ [System.IO.Stream] $file = $null;
+ [System.Security.Cryptography.MD5] $md5 = $null;
+ try
+ {
+ $md5 = [System.Security.Cryptography.MD5]::Create()
+ $file = [System.IO.File]::OpenRead($filePath)
+ return [System.BitConverter]::ToString($md5.ComputeHash($file))
+ }
+ finally
+ {
+ if ($file -ne $null)
+ {
+ $file.Dispose()
+ }
+ }
+}
+
+function GetProxyEnabledWebClient
+{
+ $wc = New-Object System.Net.WebClient
+ $proxy = [System.Net.WebRequest]::GetSystemWebProxy()
+ $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
+ $wc.Proxy = $proxy
+ return $wc
+}
+
+Write-Host "Preparing to run build script..."
+
+if(!$PSScriptRoot){
+ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
+}
+
+$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
+$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins"
+$MODULES_DIR = Join-Path $TOOLS_DIR "Modules"
+$NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe"
+$CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe"
+$NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
+$PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config"
+$PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum"
+$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config"
+$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config"
+
+# Make sure tools folder exists
+if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) {
+ Write-Verbose -Message "Creating tools directory..."
+ New-Item -Path $TOOLS_DIR -Type directory | out-null
+}
+
+# Make sure that packages.config exist.
+if (!(Test-Path $PACKAGES_CONFIG)) {
+ Write-Verbose -Message "Downloading packages.config..."
+ try {
+ $wc = GetProxyEnabledWebClient
+ $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch {
+ Throw "Could not download packages.config."
+ }
+}
+
+# Try find NuGet.exe in path if not exists
+if (!(Test-Path $NUGET_EXE)) {
+ Write-Verbose -Message "Trying to find nuget.exe in PATH..."
+ $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) }
+ $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1
+ if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) {
+ Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)."
+ $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName
+ }
+}
+
+# Try download NuGet.exe if not exists
+if (!(Test-Path $NUGET_EXE)) {
+ Write-Verbose -Message "Downloading NuGet.exe..."
+ try {
+ $wc = GetProxyEnabledWebClient
+ $wc.DownloadFile($NUGET_URL, $NUGET_EXE)
+ } catch {
+ Throw "Could not download NuGet.exe."
+ }
+}
+
+# Save nuget.exe path to environment to be available to child processed
+$ENV:NUGET_EXE = $NUGET_EXE
+
+# Restore tools from NuGet?
+if(-Not $SkipToolPackageRestore.IsPresent) {
+ Push-Location
+ Set-Location $TOOLS_DIR
+
+ # Check for changes in packages.config and remove installed tools if true.
+ [string] $md5Hash = MD5HashFile($PACKAGES_CONFIG)
+ if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or
+ ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) {
+ Write-Verbose -Message "Missing or changed package.config hash..."
+ Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery |
+ Remove-Item -Recurse
+ }
+
+ Write-Verbose -Message "Restoring tools from NuGet..."
+ $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`""
+
+ if ($LASTEXITCODE -ne 0) {
+ Throw "An error occurred while restoring NuGet tools."
+ }
+ else
+ {
+ $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII"
+ }
+ Write-Verbose -Message ($NuGetOutput | out-string)
+
+ Pop-Location
+}
+
+# Restore addins from NuGet
+if (Test-Path $ADDINS_PACKAGES_CONFIG) {
+ Push-Location
+ Set-Location $ADDINS_DIR
+
+ Write-Verbose -Message "Restoring addins from NuGet..."
+ $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`""
+
+ if ($LASTEXITCODE -ne 0) {
+ Throw "An error occurred while restoring NuGet addins."
+ }
+
+ Write-Verbose -Message ($NuGetOutput | out-string)
+
+ Pop-Location
+}
+
+# Restore modules from NuGet
+if (Test-Path $MODULES_PACKAGES_CONFIG) {
+ Push-Location
+ Set-Location $MODULES_DIR
+
+ Write-Verbose -Message "Restoring modules from NuGet..."
+ $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`""
+
+ if ($LASTEXITCODE -ne 0) {
+ Throw "An error occurred while restoring NuGet modules."
+ }
+
+ Write-Verbose -Message ($NuGetOutput | out-string)
+
+ Pop-Location
+}
+
+# Make sure that Cake has been installed.
+if (!(Test-Path $CAKE_EXE)) {
+ Throw "Could not find Cake.exe at $CAKE_EXE"
+}
+
+
+
+# Build Cake arguments
+$cakeArguments = @("$Script");
+if ($Target) { $cakeArguments += "-target=$Target" }
+if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
+if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
+if ($ShowDescription) { $cakeArguments += "-showdescription" }
+if ($DryRun) { $cakeArguments += "-dryrun" }
+if ($Experimental) { $cakeArguments += "-experimental" }
+if ($Mono) { $cakeArguments += "-mono" }
+$cakeArguments += $ScriptArgs
+
+# Start Cake
+Write-Host "Running build script..."
+&$CAKE_EXE $cakeArguments
+exit $LASTEXITCODE
diff --git a/ImageResizer/setup/Bundle/Bundle.wixproj b/ImageResizer/setup/Bundle/Bundle.wixproj
new file mode 100644
index 000000000000..a0bb50ac8511
--- /dev/null
+++ b/ImageResizer/setup/Bundle/Bundle.wixproj
@@ -0,0 +1,63 @@
+
+
+
+ Debug
+ x86
+ 3.10
+ e75ae740-ce28-40d1-bcfa-547a30edbf09
+ 2.0
+ ImageResizerSetup
+ Bundle
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ Debug
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+
+
+
+
+
+
+ $(WixExtDir)\WixNetFxExtension.dll
+ WixNetFxExtension
+
+
+ $(WixExtDir)\WixBalExtension.dll
+ WixBalExtension
+
+
+
+
+
+
+
+
+
+ Msi
+ {c6ff3d16-7935-4100-9ca1-2a45a3f7a058}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/setup/Bundle/Bundle.wxs b/ImageResizer/setup/Bundle/Bundle.wxs
new file mode 100644
index 000000000000..d86fc275a0a9
--- /dev/null
+++ b/ImageResizer/setup/Bundle/Bundle.wxs
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/setup/Bundle/ImageResizer.ico b/ImageResizer/setup/Bundle/ImageResizer.ico
new file mode 100644
index 000000000000..accd1ee6b460
Binary files /dev/null and b/ImageResizer/setup/Bundle/ImageResizer.ico differ
diff --git a/ImageResizer/setup/Bundle/ImageResizer.png b/ImageResizer/setup/Bundle/ImageResizer.png
new file mode 100644
index 000000000000..f196da96a8f9
Binary files /dev/null and b/ImageResizer/setup/Bundle/ImageResizer.png differ
diff --git a/ImageResizer/setup/Bundle/MIT.rtf b/ImageResizer/setup/Bundle/MIT.rtf
new file mode 100644
index 000000000000..320e996ab3de
Binary files /dev/null and b/ImageResizer/setup/Bundle/MIT.rtf differ
diff --git a/ImageResizer/setup/Msi/Msi.wixproj b/ImageResizer/setup/Msi/Msi.wixproj
new file mode 100644
index 000000000000..36085806b267
--- /dev/null
+++ b/ImageResizer/setup/Msi/Msi.wixproj
@@ -0,0 +1,63 @@
+
+
+
+ Debug
+ x86
+ 3.10
+ c6ff3d16-7935-4100-9ca1-2a45a3f7a058
+ 2.0
+ ImageResizer-x86
+ Package
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ Debug
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+
+
+
+
+
+
+
+ $(WixExtDir)\WixNetFxExtension.dll
+ WixNetFxExtension
+
+
+
+
+ ImageResizer
+ {2be46397-4dfa-414c-9bd4-41e4bbf8cb34}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+ ShellExtensions
+ {0b43679e-edfa-4da0-ad30-f4628b308b1b}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/setup/Msi/Product.wxs b/ImageResizer/setup/Msi/Product.wxs
new file mode 100644
index 000000000000..aaf504abf824
--- /dev/null
+++ b/ImageResizer/setup/Msi/Product.wxs
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/setup/Msi/Resources.wxs b/ImageResizer/setup/Msi/Resources.wxs
new file mode 100644
index 000000000000..93373ee8bfd5
--- /dev/null
+++ b/ImageResizer/setup/Msi/Resources.wxs
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/setup/X64Msi/Product.wxs b/ImageResizer/setup/X64Msi/Product.wxs
new file mode 100644
index 000000000000..0cedaff87f1f
--- /dev/null
+++ b/ImageResizer/setup/X64Msi/Product.wxs
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/setup/X64Msi/X64Msi.wixproj b/ImageResizer/setup/X64Msi/X64Msi.wixproj
new file mode 100644
index 000000000000..38ef40429a24
--- /dev/null
+++ b/ImageResizer/setup/X64Msi/X64Msi.wixproj
@@ -0,0 +1,57 @@
+
+
+
+ Debug
+ x86
+ 3.10
+ ea394f60-7616-4ddb-9f45-60f585460364
+ 2.0
+ ImageResizer-x64
+ Package
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+ Debug
+
+
+ bin\$(Configuration)\
+ obj\$(Configuration)\
+
+
+ Debug
+ bin\$(Platform)\$(Configuration)\
+ obj\$(Platform)\$(Configuration)\
+
+
+ bin\$(Platform)\$(Configuration)\
+ obj\$(Platform)\$(Configuration)\
+
+
+
+
+
+
+ ShellExtensions
+ {0b43679e-edfa-4da0-ad30-f4628b308b1b}
+ True
+ True
+ Binaries;Content;Satellites
+ INSTALLFOLDER
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/App.config b/ImageResizer/src/ImageResizer/App.config
new file mode 100644
index 000000000000..088ab21a4930
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/App.xaml b/ImageResizer/src/ImageResizer/App.xaml
new file mode 100644
index 000000000000..0f47c9107940
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/App.xaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/App.xaml.cs b/ImageResizer/src/ImageResizer/App.xaml.cs
new file mode 100644
index 000000000000..378c5ae09a21
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/App.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Text;
+using System.Windows;
+using GalaSoft.MvvmLight.Threading;
+using ImageResizer.Models;
+using ImageResizer.Properties;
+using ImageResizer.ViewModels;
+using ImageResizer.Views;
+
+namespace ImageResizer
+{
+ public partial class App : Application
+ {
+ static App()
+ {
+ Console.InputEncoding = Encoding.Unicode;
+ DispatcherHelper.Initialize();
+ }
+
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ var batch = ResizeBatch.FromCommandLine(Console.In, e.Args);
+
+ // TODO: Add command-line parameters that can be used in lieu of the input page (issue #14)
+ new MainWindow(new MainViewModel(batch, Settings.Default)).Show();
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Extensions/AssemblyExtensions.cs b/ImageResizer/src/ImageResizer/Extensions/AssemblyExtensions.cs
new file mode 100644
index 000000000000..ba03e431e92a
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Extensions/AssemblyExtensions.cs
@@ -0,0 +1,11 @@
+using System.Linq;
+
+namespace System.Reflection
+{
+ static class AssemblyExtensions
+ {
+ public static T GetCustomAttribute(this Assembly assembly)
+ where T : Attribute
+ => (T)assembly.GetCustomAttributes(typeof(T), inherit: false).SingleOrDefault();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Extensions/BitmapEncoderExtensions.cs b/ImageResizer/src/ImageResizer/Extensions/BitmapEncoderExtensions.cs
new file mode 100644
index 000000000000..bf67501ec4fa
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Extensions/BitmapEncoderExtensions.cs
@@ -0,0 +1,19 @@
+namespace System.Windows.Media.Imaging
+{
+ static class BitmapEncoderExtensions
+ {
+ public static bool CanEncode(this BitmapEncoder encoder)
+ {
+ try
+ {
+ var _ = encoder.CodecInfo;
+ }
+ catch (NotSupportedException)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Extensions/ICollectionExtensions.cs b/ImageResizer/src/ImageResizer/Extensions/ICollectionExtensions.cs
new file mode 100644
index 000000000000..80f796d7249a
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Extensions/ICollectionExtensions.cs
@@ -0,0 +1,11 @@
+namespace System.Collections.Generic
+{
+ static class ICollectionExtensions
+ {
+ public static void AddRange(this ICollection collection, IEnumerable items)
+ {
+ foreach (var item in items)
+ collection.Add(item);
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Extensions/TimeSpanExtensions.cs b/ImageResizer/src/ImageResizer/Extensions/TimeSpanExtensions.cs
new file mode 100644
index 000000000000..8bbecc6c9f17
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Extensions/TimeSpanExtensions.cs
@@ -0,0 +1,8 @@
+namespace System
+{
+ static class TimeSpanExtensions
+ {
+ public static TimeSpan Multiply(this TimeSpan timeSpan, double scalar)
+ => new TimeSpan((long)(timeSpan.Ticks * scalar));
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ImageResizer.csproj b/ImageResizer/src/ImageResizer/ImageResizer.csproj
new file mode 100644
index 000000000000..0ddde5962bae
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ImageResizer.csproj
@@ -0,0 +1,183 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}
+ WinExe
+ ImageResizer
+ ImageResizer
+ v4.0
+ 512
+ {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ 4
+ Client
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ false
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ Resources\ImageResizer.ico
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ AdvancedWindow.xaml
+
+
+
+
+ ProgressPage.xaml
+
+
+
+ ResultsPage.xaml
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+ InputPage.xaml
+
+
+ MainWindow.xaml
+ Code
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ Code
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PublicResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+
+
+
+
+ PublicSettingsSingleFileGenerator
+ Designer
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5.4.1
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Models/CustomSize.cs b/ImageResizer/src/ImageResizer/Models/CustomSize.cs
new file mode 100644
index 000000000000..c5875ea2c1f9
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/CustomSize.cs
@@ -0,0 +1,13 @@
+using ImageResizer.Properties;
+
+namespace ImageResizer.Models
+{
+ public class CustomSize : ResizeSize
+ {
+ public override string Name
+ {
+ get => Resources.Input_Custom;
+ set { /* no-op */ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeBatch.cs b/ImageResizer/src/ImageResizer/Models/ResizeBatch.cs
new file mode 100644
index 000000000000..0e30bc124dc0
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeBatch.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Models
+{
+ public class ResizeBatch
+ {
+ public string DestinationDirectory { get; set; }
+ public ICollection Files { get; } = new List();
+
+ public static ResizeBatch FromCommandLine(TextReader standardInput, string[] args)
+ {
+ var batch = new ResizeBatch();
+
+ // NB: We read these from stdin since there are limits on the number of args you can have
+ string file;
+ while ((file = standardInput.ReadLine()) != null)
+ batch.Files.Add(file);
+
+ for (var i = 0; i < args.Length; i++)
+ {
+ if (args[i] == "/d")
+ {
+ batch.DestinationDirectory = args[++i];
+ continue;
+ }
+
+ batch.Files.Add(args[i]);
+ }
+
+ return batch;
+ }
+
+ public IEnumerable Process(
+ CancellationToken cancellationToken,
+ Action reportProgress)
+ {
+ double total = Files.Count;
+ var completed = 0;
+ var errors = new ConcurrentBag();
+
+ // TODO: If we ever switch to Windows.Graphics.Imaging, we can get a lot more throughput by using the async
+ // APIs and a custom SynchronizationContext
+ Parallel.ForEach(
+ Files,
+ new ParallelOptions
+ {
+ CancellationToken = cancellationToken,
+ MaxDegreeOfParallelism = Environment.ProcessorCount
+ },
+ (file, state, i) =>
+ {
+ try
+ {
+ Execute(file);
+ }
+ catch (Exception ex)
+ {
+ errors.Add(new ResizeError { File = Path.GetFileName(file), Error = ex.Message });
+ }
+
+ Interlocked.Increment(ref completed);
+
+ reportProgress(completed, total);
+ });
+
+ return errors;
+ }
+
+ protected virtual void Execute(string file)
+ => new ResizeOperation(file, DestinationDirectory, Settings.Default).Execute();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeError.cs b/ImageResizer/src/ImageResizer/Models/ResizeError.cs
new file mode 100644
index 000000000000..fa5636d82118
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeError.cs
@@ -0,0 +1,8 @@
+namespace ImageResizer.Models
+{
+ public class ResizeError
+ {
+ public string File { get; set; }
+ public string Error { get; set; }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeFit.cs b/ImageResizer/src/ImageResizer/Models/ResizeFit.cs
new file mode 100644
index 000000000000..bb896e6593d1
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeFit.cs
@@ -0,0 +1,9 @@
+namespace ImageResizer.Models
+{
+ public enum ResizeFit
+ {
+ Fill,
+ Fit,
+ Stretch
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeOperation.cs b/ImageResizer/src/ImageResizer/Models/ResizeOperation.cs
new file mode 100644
index 000000000000..3b7e63fa1ccc
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeOperation.cs
@@ -0,0 +1,194 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using ImageResizer.Properties;
+using ImageResizer.Utilities;
+using Microsoft.VisualBasic.FileIO;
+
+namespace ImageResizer.Models
+{
+ class ResizeOperation
+ {
+ readonly string _file;
+ readonly string _destinationDirectory;
+ readonly Settings _settings;
+
+ public ResizeOperation(string file, string destinationDirectory, Settings settings)
+ {
+ _file = file;
+ _destinationDirectory = destinationDirectory;
+ _settings = settings;
+ }
+
+ public void Execute()
+ {
+ string path;
+ using (var inputStream = File.OpenRead(_file))
+ {
+ var decoder = BitmapDecoder.Create(
+ inputStream,
+ BitmapCreateOptions.PreservePixelFormat,
+ BitmapCacheOption.None);
+
+ var encoder = BitmapEncoder.Create(decoder.CodecInfo.ContainerFormat);
+ if (!encoder.CanEncode())
+ encoder = BitmapEncoder.Create(_settings.FallbackEncoder);
+
+ ConfigureEncoder(encoder);
+
+ if (decoder.Metadata != null)
+ {
+ try
+ {
+ encoder.Metadata = decoder.Metadata;
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ }
+
+ if (decoder.Palette != null)
+ encoder.Palette = decoder.Palette;
+
+ foreach (var originalFrame in decoder.Frames)
+ {
+ encoder.Frames.Add(
+ BitmapFrame.Create(
+ Transform(originalFrame),
+ thumbnail: null,
+ // TODO: Add an option to strip any metadata that doesn't affect rendering (issue #3)
+ (BitmapMetadata)originalFrame.Metadata,
+ colorContexts: null));
+ }
+
+ path = GetDestinationPath(encoder);
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+ using (var outputStream = File.Open(path, FileMode.CreateNew, FileAccess.Write))
+ encoder.Save(outputStream);
+ }
+
+ if (_settings.KeepDateModified)
+ File.SetLastWriteTimeUtc(path, File.GetLastWriteTimeUtc(_file));
+
+ if (_settings.Replace)
+ {
+ var backup = GetBackupPath();
+ File.Replace(path, _file, backup, ignoreMetadataErrors: true);
+ FileSystem.DeleteFile(backup, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
+ }
+ }
+
+ void ConfigureEncoder(BitmapEncoder encoder)
+ {
+ switch (encoder)
+ {
+ case JpegBitmapEncoder jpegEncoder:
+ jpegEncoder.QualityLevel = MathHelpers.Clamp(_settings.JpegQualityLevel, 1, 100);
+ break;
+
+ case PngBitmapEncoder pngBitmapEncoder:
+ pngBitmapEncoder.Interlace = _settings.PngInterlaceOption;
+ break;
+
+ case TiffBitmapEncoder tiffEncoder:
+ tiffEncoder.Compression = _settings.TiffCompressOption;
+ break;
+ }
+ }
+
+ BitmapSource Transform(BitmapSource source)
+ {
+ var originalWidth = source.PixelWidth;
+ var originalHeight = source.PixelHeight;
+ var width = _settings.SelectedSize.GetPixelWidth(originalWidth, source.DpiX);
+ var height = _settings.SelectedSize.GetPixelHeight(originalHeight, source.DpiY);
+
+ if (_settings.IgnoreOrientation
+ && !_settings.SelectedSize.HasAuto
+ && _settings.SelectedSize.Unit != ResizeUnit.Percent
+ && originalWidth < originalHeight != (width < height))
+ {
+ var temp = width;
+ width = height;
+ height = temp;
+ }
+
+ var scaleX = width / originalWidth;
+ var scaleY = height / originalHeight;
+
+ if (_settings.SelectedSize.Fit == ResizeFit.Fit)
+ {
+ scaleX = Math.Min(scaleX, scaleY);
+ scaleY = scaleX;
+ }
+ else if (_settings.SelectedSize.Fit == ResizeFit.Fill)
+ {
+ scaleX = Math.Max(scaleX, scaleY);
+ scaleY = scaleX;
+ }
+
+ if (_settings.ShrinkOnly
+ && _settings.SelectedSize.Unit != ResizeUnit.Percent
+ && (scaleX >= 1 || scaleY >= 1))
+ return source;
+
+ var scaledBitmap = new TransformedBitmap(source, new ScaleTransform(scaleX, scaleY));
+ if (_settings.SelectedSize.Fit == ResizeFit.Fill
+ && (scaledBitmap.PixelWidth > width
+ || scaledBitmap.PixelHeight > height))
+ {
+ var x = (int)(((originalWidth * scaleX) - width) / 2);
+ var y = (int)(((originalHeight * scaleY) - height) / 2);
+
+ return new CroppedBitmap(scaledBitmap, new Int32Rect(x, y, (int)width, (int)height));
+ }
+
+ return scaledBitmap;
+ }
+
+ string GetDestinationPath(BitmapEncoder encoder)
+ {
+ var directory = _destinationDirectory ?? Path.GetDirectoryName(_file);
+ var originalFileName = Path.GetFileNameWithoutExtension(_file);
+
+ var supportedExtensions = encoder.CodecInfo.FileExtensions.Split(',');
+ var extension = Path.GetExtension(_file);
+ if (!supportedExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
+ {
+ extension = supportedExtensions.FirstOrDefault();
+ }
+
+ var fileName = string.Format(
+ _settings.FileNameFormat,
+ originalFileName,
+ _settings.SelectedSize.Name,
+ _settings.SelectedSize.Width,
+ _settings.SelectedSize.Height,
+ encoder.Frames[0].PixelWidth,
+ encoder.Frames[0].PixelHeight);
+ var path = Path.Combine(directory, fileName + extension);
+ var uniquifier = 1;
+ while (File.Exists(path))
+ path = Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + extension);
+
+ return path;
+ }
+
+ string GetBackupPath()
+ {
+ var directory = Path.GetDirectoryName(_file);
+ var fileName = Path.GetFileNameWithoutExtension(_file);
+ var extension = Path.GetExtension(_file);
+
+ var path = Path.Combine(directory, fileName + ".bak" + extension);
+ var uniquifier = 1;
+ while (File.Exists(path))
+ path = Path.Combine(directory, fileName + " (" + uniquifier++ + ")" + ".bak" + extension);
+
+ return path;
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeSize.cs b/ImageResizer/src/ImageResizer/Models/ResizeSize.cs
new file mode 100644
index 000000000000..e1679f251ef1
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeSize.cs
@@ -0,0 +1,124 @@
+using System.Collections.Generic;
+using System.Diagnostics;
+using GalaSoft.MvvmLight;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Models
+{
+ public class ResizeSize : ObservableObject
+ {
+ static readonly IDictionary _tokens;
+
+ string _name;
+ ResizeFit _fit = ResizeFit.Fit;
+ double _width;
+ double _height;
+ bool _showHeight = true;
+ ResizeUnit _unit = ResizeUnit.Pixel;
+
+ static ResizeSize()
+ => _tokens = new Dictionary
+ {
+ ["$small$"] = Resources.Small,
+ ["$medium$"] = Resources.Medium,
+ ["$large$"] = Resources.Large,
+ ["$phone$"] = Resources.Phone
+ };
+
+ public virtual string Name
+ {
+ get => _name;
+ set => Set(nameof(Name), ref _name, ReplaceTokens(value));
+ }
+
+ public ResizeFit Fit
+ {
+ get => _fit;
+ set
+ {
+ if (Set(nameof(Fit), ref _fit, value))
+ UpdateShowHeight();
+ }
+ }
+
+ public double Width
+ {
+ get => _width;
+ set => Set(nameof(Width), ref _width, value);
+ }
+
+ public double Height
+ {
+ get => _height;
+ set => Set(nameof(Height), ref _height, value);
+ }
+
+ public bool ShowHeight
+ => _showHeight;
+
+ public bool HasAuto
+ => Width == 0 || Height == 0;
+
+ public ResizeUnit Unit
+ {
+ get => _unit;
+ set
+ {
+ if (Set(nameof(Unit), ref _unit, value))
+ UpdateShowHeight();
+ }
+ }
+
+ public double GetPixelWidth(int originalWidth, double dpi)
+ => ConvertToPixels(Width, Unit, originalWidth, dpi);
+
+ public double GetPixelHeight(int originalHeight, double dpi)
+ => ConvertToPixels(
+ Fit != ResizeFit.Stretch && Unit == ResizeUnit.Percent
+ ? Width
+ : Height,
+ Unit,
+ originalHeight,
+ dpi);
+
+ static string ReplaceTokens(string text)
+ => (text != null && _tokens.TryGetValue(text, out var result))
+ ? result
+ : text;
+
+ void UpdateShowHeight()
+ => Set(
+ nameof(ShowHeight),
+ ref _showHeight,
+ Fit == ResizeFit.Stretch || Unit != ResizeUnit.Percent);
+
+ double ConvertToPixels(double value, ResizeUnit unit, int originalValue, double dpi)
+ {
+ if (value == 0)
+ {
+ if (Fit == ResizeFit.Fit)
+ return double.PositiveInfinity;
+
+ Debug.Assert(Fit == ResizeFit.Fill || Fit == ResizeFit.Stretch, "Unexpected ResizeFit value: " + Fit);
+
+ return originalValue;
+ }
+
+ switch (unit)
+ {
+ case ResizeUnit.Inch:
+ return value * dpi;
+
+ case ResizeUnit.Centimeter:
+ return value * dpi / 2.54;
+
+ case ResizeUnit.Percent:
+ return value / 100 * originalValue;
+
+ default:
+ Debug.Assert(unit == ResizeUnit.Pixel, "Unexpected unit value: " + unit);
+ return value;
+ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Models/ResizeUnit.cs b/ImageResizer/src/ImageResizer/Models/ResizeUnit.cs
new file mode 100644
index 000000000000..719dccf77076
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Models/ResizeUnit.cs
@@ -0,0 +1,10 @@
+namespace ImageResizer.Models
+{
+ public enum ResizeUnit
+ {
+ Centimeter,
+ Inch,
+ Percent,
+ Pixel
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Properties/AssemblyInfo.cs b/ImageResizer/src/ImageResizer/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000000..336dd51a5905
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/AssemblyInfo.cs
@@ -0,0 +1,56 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Image Resizer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Brice Lambson")]
+[assembly: AssemblyProduct("Image Resizer for Windows")]
+[assembly: AssemblyCopyright("© 2019 Brice Lambson. All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+[assembly: NeutralResourcesLanguage("en-US")]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.1.3.0")]
+[assembly: AssemblyFileVersion("3.1.3.0")]
+[assembly: AssemblyInformationalVersion("3.1.3")]
+
diff --git a/ImageResizer/src/ImageResizer/Properties/InternalsVisibleTo.cs b/ImageResizer/src/ImageResizer/Properties/InternalsVisibleTo.cs
new file mode 100644
index 000000000000..c3a708ba921e
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/InternalsVisibleTo.cs
@@ -0,0 +1,3 @@
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("ImageResizer.Test")]
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.Designer.cs b/ImageResizer/src/ImageResizer/Properties/Resources.Designer.cs
new file mode 100644
index 000000000000..500cac4970f1
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.Designer.cs
@@ -0,0 +1,738 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ImageResizer.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ public class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ImageResizer.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ public static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About.
+ ///
+ public static string Advanced_About {
+ get {
+ return ResourceManager.GetString("Advanced_About", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Create a new size.
+ ///
+ public static string Advanced_CreateSize {
+ get {
+ return ResourceManager.GetString("Advanced_CreateSize", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Delete.
+ ///
+ public static string Advanced_DeleteSize {
+ get {
+ return ResourceManager.GetString("Advanced_DeleteSize", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Encoding.
+ ///
+ public static string Advanced_Encoding {
+ get {
+ return ResourceManager.GetString("Advanced_Encoding", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Fallback encoder:.
+ ///
+ public static string Advanced_FallbackEncoder {
+ get {
+ return ResourceManager.GetString("Advanced_FallbackEncoder", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to File.
+ ///
+ public static string Advanced_File {
+ get {
+ return ResourceManager.GetString("Advanced_File", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Filename:.
+ ///
+ public static string Advanced_FileName {
+ get {
+ return ResourceManager.GetString("Advanced_FileName", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Original filename.
+ ///
+ public static string Advanced_FileNameToken1 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Size name.
+ ///
+ public static string Advanced_FileNameToken2 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Selected width.
+ ///
+ public static string Advanced_FileNameToken3 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken3", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Selected height.
+ ///
+ public static string Advanced_FileNameToken4 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken4", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Actual width (pixels).
+ ///
+ public static string Advanced_FileNameToken5 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken5", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Actual height (pixels).
+ ///
+ public static string Advanced_FileNameToken6 {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameToken6", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The following parameters can be used..
+ ///
+ public static string Advanced_FileNameTokens {
+ get {
+ return ResourceManager.GetString("Advanced_FileNameTokens", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _JPEG quality level:.
+ ///
+ public static string Advanced_JpegQualityLevel {
+ get {
+ return ResourceManager.GetString("Advanced_JpegQualityLevel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Use original date modified.
+ ///
+ public static string Advanced_KeepDateModified {
+ get {
+ return ResourceManager.GetString("Advanced_KeepDateModified", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _PNG interlacing:.
+ ///
+ public static string Advanced_PngInterlaceOption {
+ get {
+ return ResourceManager.GetString("Advanced_PngInterlaceOption", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Sizes.
+ ///
+ public static string Advanced_Sizes {
+ get {
+ return ResourceManager.GetString("Advanced_Sizes", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _TIFF compression:.
+ ///
+ public static string Advanced_TiffCompressOption {
+ get {
+ return ResourceManager.GetString("Advanced_TiffCompressOption", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Advanced Options.
+ ///
+ public static string Advanced_Title {
+ get {
+ return ResourceManager.GetString("Advanced_Title", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to All Files.
+ ///
+ public static string AllFilesFilter {
+ get {
+ return ResourceManager.GetString("AllFilesFilter", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cancel.
+ ///
+ public static string Cancel {
+ get {
+ return ResourceManager.GetString("Cancel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to © 2019 Brice Lambson. All rights reserved..
+ ///
+ public static string Copyright {
+ get {
+ return ResourceManager.GetString("Copyright", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Image Resizer for Windows.
+ ///
+ public static string ImageResizer {
+ get {
+ return ResourceManager.GetString("ImageResizer", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (auto).
+ ///
+ public static string Input_Auto {
+ get {
+ return ResourceManager.GetString("Input_Auto", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Select a size..
+ ///
+ public static string Input_Content {
+ get {
+ return ResourceManager.GetString("Input_Content", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Custom.
+ ///
+ public static string Input_Custom {
+ get {
+ return ResourceManager.GetString("Input_Custom", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Ign_ore the orientation of pictures.
+ ///
+ public static string Input_IgnoreOrientation {
+ get {
+ return ResourceManager.GetString("Input_IgnoreOrientation", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Resize your pictures.
+ ///
+ public static string Input_MainInstruction {
+ get {
+ return ResourceManager.GetString("Input_MainInstruction", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to R_esize the original pictures (don't create copies).
+ ///
+ public static string Input_Replace {
+ get {
+ return ResourceManager.GetString("Input_Replace", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Resize.
+ ///
+ public static string Input_Resize {
+ get {
+ return ResourceManager.GetString("Input_Resize", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Advanced options....
+ ///
+ public static string Input_ShowAdvanced {
+ get {
+ return ResourceManager.GetString("Input_ShowAdvanced", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Make pictures smaller but not larger.
+ ///
+ public static string Input_ShrinkOnly {
+ get {
+ return ResourceManager.GetString("Input_ShrinkOnly", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Large.
+ ///
+ public static string Large {
+ get {
+ return ResourceManager.GetString("Large", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Medium.
+ ///
+ public static string Medium {
+ get {
+ return ResourceManager.GetString("Medium", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to OK.
+ ///
+ public static string OK {
+ get {
+ return ResourceManager.GetString("OK", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Phone.
+ ///
+ public static string Phone {
+ get {
+ return ResourceManager.GetString("Phone", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to All Picture Files.
+ ///
+ public static string PictureFilter {
+ get {
+ return ResourceManager.GetString("PictureFilter", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (Default).
+ ///
+ public static string PngInterlaceOption_Default {
+ get {
+ return ResourceManager.GetString("PngInterlaceOption_Default", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Off.
+ ///
+ public static string PngInterlaceOption_Off {
+ get {
+ return ResourceManager.GetString("PngInterlaceOption_Off", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to On.
+ ///
+ public static string PngInterlaceOption_On {
+ get {
+ return ResourceManager.GetString("PngInterlaceOption_On", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Resizing your pictures....
+ ///
+ public static string Progress_MainInstruction {
+ get {
+ return ResourceManager.GetString("Progress_MainInstruction", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to _Stop.
+ ///
+ public static string Progress_Stop {
+ get {
+ return ResourceManager.GetString("Progress_Stop", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {0} hour, {1} minute remaining..
+ ///
+ public static string Progress_TimeRemaining_HourMinute {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_HourMinute", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {0} hour, {1} minutes remaining..
+ ///
+ public static string Progress_TimeRemaining_HourMinutes {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_HourMinutes", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {0} hours, {1} minute remaining..
+ ///
+ public static string Progress_TimeRemaining_HoursMinute {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_HoursMinute", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {0} hours, {1} minutes remaining..
+ ///
+ public static string Progress_TimeRemaining_HoursMinutes {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_HoursMinutes", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {1} minute, {2} second remaining..
+ ///
+ public static string Progress_TimeRemaining_MinuteSecond {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_MinuteSecond", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {1} minute, {2} seconds remaining..
+ ///
+ public static string Progress_TimeRemaining_MinuteSeconds {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_MinuteSeconds", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {1} minutes, {2} second remaining..
+ ///
+ public static string Progress_TimeRemaining_MinutesSecond {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_MinutesSecond", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {1} minutes, {2} seconds remaining..
+ ///
+ public static string Progress_TimeRemaining_MinutesSeconds {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_MinutesSeconds", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {2} second remaining..
+ ///
+ public static string Progress_TimeRemaining_Second {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_Second", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to About {2} seconds remaining..
+ ///
+ public static string Progress_TimeRemaining_Seconds {
+ get {
+ return ResourceManager.GetString("Progress_TimeRemaining_Seconds", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Fill.
+ ///
+ public static string ResizeFit_Fill {
+ get {
+ return ResourceManager.GetString("ResizeFit_Fill", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to fills.
+ ///
+ public static string ResizeFit_Fill_ThirdPersonSingular {
+ get {
+ return ResourceManager.GetString("ResizeFit_Fill_ThirdPersonSingular", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Fit.
+ ///
+ public static string ResizeFit_Fit {
+ get {
+ return ResourceManager.GetString("ResizeFit_Fit", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to fits within.
+ ///
+ public static string ResizeFit_Fit_ThirdPersonSingular {
+ get {
+ return ResourceManager.GetString("ResizeFit_Fit_ThirdPersonSingular", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Stretch.
+ ///
+ public static string ResizeFit_Stretch {
+ get {
+ return ResourceManager.GetString("ResizeFit_Stretch", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to stretches to.
+ ///
+ public static string ResizeFit_Stretch_ThirdPersonSingular {
+ get {
+ return ResourceManager.GetString("ResizeFit_Stretch_ThirdPersonSingular", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Centimeters.
+ ///
+ public static string ResizeUnit_Centimeter {
+ get {
+ return ResourceManager.GetString("ResizeUnit_Centimeter", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Inches.
+ ///
+ public static string ResizeUnit_Inch {
+ get {
+ return ResourceManager.GetString("ResizeUnit_Inch", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Percent.
+ ///
+ public static string ResizeUnit_Percent {
+ get {
+ return ResourceManager.GetString("ResizeUnit_Percent", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Pixels.
+ ///
+ public static string ResizeUnit_Pixel {
+ get {
+ return ResourceManager.GetString("ResizeUnit_Pixel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Close.
+ ///
+ public static string Results_Close {
+ get {
+ return ResourceManager.GetString("Results_Close", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Can't resize the following pictures.
+ ///
+ public static string Results_MainInstruction {
+ get {
+ return ResourceManager.GetString("Results_MainInstruction", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Small.
+ ///
+ public static string Small {
+ get {
+ return ResourceManager.GetString("Small", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CCITT3.
+ ///
+ public static string TiffCompressOption_Ccitt3 {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Ccitt3", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CCITT4.
+ ///
+ public static string TiffCompressOption_Ccitt4 {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Ccitt4", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to (Default).
+ ///
+ public static string TiffCompressOption_Default {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Default", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to LZW.
+ ///
+ public static string TiffCompressOption_Lzw {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Lzw", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to None.
+ ///
+ public static string TiffCompressOption_None {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_None", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to RLE.
+ ///
+ public static string TiffCompressOption_Rle {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Rle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Zip.
+ ///
+ public static string TiffCompressOption_Zip {
+ get {
+ return ResourceManager.GetString("TiffCompressOption_Zip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Value must be between '{0}' and '{1}'..
+ ///
+ public static string ValueMustBeBetween {
+ get {
+ return ResourceManager.GetString("ValueMustBeBetween", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Version.
+ ///
+ public static string Version {
+ get {
+ return ResourceManager.GetString("Version", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.ar.resx b/ImageResizer/src/ImageResizer/Properties/Resources.ar.resx
new file mode 100644
index 000000000000..f4e50bce69a7
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.ar.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ حول
+
+
+ إنشاء حجم جديد
+
+
+ حذف
+
+
+ الترميز
+
+
+ _Fallback encoder:
+
+
+ ملف
+
+
+ الإسم
+
+
+ اسم الملف الأصلي
+
+
+ اسم هذا الحجم
+
+
+ العرض المحدد
+
+
+ الارتفاع المحدد
+
+
+ العرض الأصلي (بكسل)
+
+
+ الارتفاع الأصلي (بكسل)
+
+
+ البارمترات التالية يمكن استخدامها.
+
+
+ مدى جودة صورة JPEG:
+
+
+ استخدام تاريخ التعديل الأصلي
+
+
+ تداخل PNG:
+
+
+ الأحجام
+
+
+ مستوى ضغط TIFF
+
+
+ إعدادات متقدمة
+
+
+ كل الملفات
+
+
+ إلغاء
+
+
+ © كل الحقوق محفوظة ل Brice Lambson 2019
+
+
+ المقياس - ويندوز
+
+
+ (تلقائي)
+
+
+ حدد المقاس
+
+
+ تخصيص
+
+
+ تجاهل اتجاه الصور
+
+
+ تغيير مقاس صورك
+
+
+ تغيير الصورة الأصلية (لا تنشئ نسخاً)
+
+
+ إعادة تحجيم
+
+
+ خيارات متقدمة
+
+
+ غير مقاس الصورة بحيث يتم تصغيرها لا تكبيرها
+
+
+ كبير
+
+
+ متوسط
+
+
+ موافق
+
+
+ الجوال
+
+
+ كل ملفات الصور
+
+
+ (افتراضي)
+
+
+ Off
+
+
+ On
+
+
+ جاري إعادة تحجيم صورك
+
+
+ أيقاف
+
+
+ باقي حوالي {0} ساعة و {1} دقيقة.
+
+
+ باقي حوالي {0} ساعة و {1} دقائق.
+
+
+ باقي حوالي {0} ساعات و {1} دقيقة.
+
+
+ باقي حوالي {0} ساعات و {1} دقائق.
+
+
+ باقي حوالي {1} دقيقة و {2} ثانية.
+
+
+ باقي حوالي {1} دقيقة و {2} ثواني.
+
+
+ باقي حوالي {1} دقائق و {2} ثواني.
+
+
+ باقي حوالي {1} دقائق و {2} ثواني.
+
+
+ باقي حوالي {2} ثانية.
+
+
+ باقي حوالي {2} ثواني.
+
+
+ تعبئة
+
+
+ تعبئة
+
+
+ ملائمة
+
+
+ ملائمة داخل
+
+
+ تمديد
+
+
+ تمديد إلى
+
+
+ سم
+
+
+ إنش
+
+
+ بالمئة
+
+
+ بكسل
+
+
+ إغلاق
+
+
+ لا يمكن إعادة تحجيم كل من الصور التالية
+
+
+ صغير
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (إفتراضي)
+
+
+ LZW
+
+
+ لا شيئ
+
+
+ RLE
+
+
+ ZIP
+
+
+ يجب أن تكون القيمة بين "{0}" و "{1}".
+
+
+ الإصدار
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.bg.resx b/ImageResizer/src/ImageResizer/Properties/Resources.bg.resx
new file mode 100644
index 000000000000..043b16f2246c
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.bg.resx
@@ -0,0 +1,348 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Относно
+
+
+ Създай нов размер
+
+
+ Изтрий
+
+
+ Енкодинг
+
+
+ _Fallback encoder:
+
+
+ Фаил
+
+
+ _Име на файл:
+
+
+ Оригинлно име на файл
+
+
+ Размер
+
+
+ Избрана ширина
+
+
+ Избрана височина
+
+
+ Реална ширина (пиксели)
+
+
+ Реална височина (пиксели)
+
+
+ Следните параметри могат да бъдат избрани.
+
+
+ _Ниво на качество JPEG:
+
+
+
+ _Използвай оригиналната дата на промяна
+
+
+ _PNG interlacing:
+
+
+ Размери
+
+
+
+ _TIFF компресиране:
+
+
+ Допълнителни настройки
+
+
+ Всички файлове
+
+
+ Отказ
+
+
+ © 2019 Brice Lambson. All rights reserved.
+
+
+ Преоразмерител на картини за Windows
+
+
+ (авто)
+
+
+ Избери размер
+
+
+ По избор
+
+
+ Пренебрегване на ориентацията
+
+
+ Преоразмери картините
+
+
+ Преоразмери оригиналните картини (не създава копия)
+
+
+ Преоразмеряване
+
+
+ Допълнителни настройки
+
+
+ Направи картините малки но не по-големи
+
+
+ Голям
+
+
+ Среден
+
+
+ OK
+
+
+ Телефон
+
+
+ Всички картинни файлове
+
+
+ (По подразбиране)
+
+
+ Изкл.
+
+
+ Вкл.
+
+
+ Преоразмеряване на Вашите картини...
+
+
+ _Стоп
+
+
+
+Остават около {0} час, {1} минута.
+
+
+ Остават около {0} час, {1} минути.
+
+
+ Остават около {0} часа, {1} минута.
+
+
+ Остават около {0} часа, {1} минути.
+
+
+ Остават около {1} минута, {2} секунда.
+
+
+ Остават около {1} минута, {2} секунди.
+
+
+ Остават около {1} минути, {2} секунда.
+
+
+ Остават около {1} минути, {2} секунди.
+
+
+ Остават около {2} секунда.
+
+
+ Остават около {2} секунди.
+
+
+ Запълни
+
+
+ Запълване
+
+
+ Побиране
+
+
+ Побиране в
+
+
+ Разпъване
+
+
+ разпъване до
+
+
+ Сантиметри
+
+
+ Инчове
+
+
+ Проценти
+
+
+ Пиксели
+
+
+ Затваряне
+
+
+ Следните картини не могат да се преоразмерят
+
+
+ Малък
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (По подразбиране)
+
+
+ LZW
+
+
+ нищо
+
+
+ RLE
+
+
+ Zip
+
+
+ Стойността трябва да бъде между '{0}' и '{1}'.
+
+
+ Версия
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.ca.resx b/ImageResizer/src/ImageResizer/Properties/Resources.ca.resx
new file mode 100644
index 000000000000..e4215aafc115
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.ca.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Quant a
+
+
+ Crea una mida nova
+
+
+ Esborra
+
+
+ Codificació
+
+
+ _Codificador de fons:
+
+
+ Fitxer
+
+
+ _Nom del fitxer:
+
+
+ Nom de fitxer original
+
+
+ Nom de la mida
+
+
+ Amplada seleccionada
+
+
+ Alçada seleccionada
+
+
+ Amplada actual (píxels)
+
+
+ Alçada actual (píxels)
+
+
+ Podeu utilitzar els paràmetres següents.
+
+
+ Nivell de qualitat _JPEG:
+
+
+ _Utilitza la data original modificada
+
+
+ _PNG: entrellaçat:
+
+
+ Mides
+
+
+ Compressió _TIFF:
+
+
+ Opcions avançades
+
+
+ Tots els fitxers
+
+
+ Cancel·la
+
+
+ © 2019 Brice Lambson. Tots els drets reservats.
+
+
+ Image Resizer per a Windows
+
+
+ (Auto)
+
+
+ _Seleccioneu una mida.
+
+
+ Personalitzat
+
+
+ Ign_oreu l'orientació de les imatges
+
+
+ Canvia la mida de les imatges
+
+
+ Canvia la _mida dels originals (sense copiar-los)
+
+
+ _Canvia la mida
+
+
+ Opcions avançades ...
+
+
+ _Imatges més petites però no més grans
+
+
+ Gran
+
+
+ Mitjà
+
+
+ D'acord
+
+
+ Telèfon
+
+
+ Tots els fitxers d'imatges
+
+
+ (Per defecte)
+
+
+ Apaga
+
+
+ Engega
+
+
+ Canviant la mida de les imatges ...
+
+
+ _Atura
+
+
+ Manca al voltant de {0} hora, {1} minuts.
+
+
+ Manca al voltant de {0} hora, {1} minuts.
+
+
+ Manca al voltant de {0} hora, {1} minuts.
+
+
+ Manca al voltant de {0} hora, {1} minuts.
+
+
+ Manca al voltant de {1} minuts, {2} segons.
+
+
+ Manca al voltant de {1} minuts, {2} segons.
+
+
+ Manca al voltant de {1} minuts, {2} segons.
+
+
+ Manca al voltant de {1} minuts, {2} segons.
+
+
+ Manca al voltant de {2} segons.
+
+
+ Manca al voltant de {2} segons.
+
+
+ Omple
+
+
+ farcits
+
+
+ Encaixa
+
+
+ encaixa dins
+
+
+ Ajusta
+
+
+ ajusta a
+
+
+ Centímetres
+
+
+ Polzades
+
+
+ Per cent
+
+
+ Píxels
+
+
+ Tanca
+
+
+ No es pot canviar la mida de les imatges següents
+
+
+ Petit
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Per defecte)
+
+
+ LZW
+
+
+ Cap
+
+
+ RLE
+
+
+ Zip
+
+
+ El valor ha de ser entre '{0}' i '{1}'.
+
+
+ Versió
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.cs.resx b/ImageResizer/src/ImageResizer/Properties/Resources.cs.resx
new file mode 100644
index 000000000000..7b7f963e1dc5
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.cs.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ O programu
+
+
+ Vytvořit novou velikost
+
+
+ Smazat
+
+
+ Kódování
+
+
+ Záložní encoder:
+
+
+ Soubor
+
+
+ Název souboru:
+
+
+ Původní název souboru
+
+
+ Název velikosti
+
+
+ Vyberte šířku
+
+
+ Vyberte výšku
+
+
+ Aktuální šířka (v pixelech)
+
+
+ Aktuální výška (v pixelech)
+
+
+ Použity mohou být následující parametry.
+
+
+ Kvalita JPEG:
+
+
+ Použít původní datum změny
+
+
+ Prokládání PNG:
+
+
+ Velikosti
+
+
+ TIFF komprese:
+
+
+ Rozšířená nastavení
+
+
+ Všechny soubory
+
+
+ Zrušit
+
+
+ © 2019 Brice Lambson. Všechna práva vyhrazena
+
+
+ Image Resizer pro Windows
+
+
+ (automaticky)
+
+
+ Vyberte soubor
+
+
+ Vlastní
+
+
+ Ignorovat _orientaci obrázků
+
+
+ Změnit velikost obrázků
+
+
+ Změnit velikost původních obrázků (nevytvářet kopie)
+
+
+ Změnit velikost
+
+
+ Rozšířená nastavení...
+
+
+ Obráz_ky pouze zmenšovat
+
+
+ Velké
+
+
+ Střední
+
+
+ OK
+
+
+ Mobilní
+
+
+ Všechny soubory obrázků
+
+
+ (Výchozí)
+
+
+ Vyp.
+
+
+ Zap.
+
+
+ Probíhá změna velikosti obrázků...
+
+
+ Zastavit
+
+
+ Zbývá přibližně {0} hodin, {1} minut.
+
+
+ Zbývá přibližně {0} hodin, {1} minut.
+
+
+ Zbývá přibližně {0} hodin, {1} minut.
+
+
+ Zbývá přibližně {0} hodin, {1} minut.
+
+
+ Zbývá přibližně {1} minut, {2} vteřin.
+
+
+ Zbývá přibližně {1} minut, {2} vteřin.
+
+
+ Zbývá přibližně {1} minut, {2} vteřin.
+
+
+ Zbývá přibližně {1} minut, {2} vteřin.
+
+
+ Zbývá přibližně {2} vteřin.
+
+
+ Zbývá přibližně {2} vteřin.
+
+
+ Vyplnit
+
+
+ vyplňuje
+
+
+ Napasovat
+
+
+ pasuje do
+
+
+ Roztažení
+
+
+ roztáhnout na
+
+
+ centimetrů
+
+
+ palců
+
+
+ procent
+
+
+ pixelů
+
+
+ Zavřít
+
+
+ Velikost následujících obrázků nelze změnit
+
+
+ Malé
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Výchozí)
+
+
+ LZW
+
+
+ Nic
+
+
+ RLE
+
+
+ Zip
+
+
+ Hodnota musí být mezi {0} a {1}.
+
+
+ Verze
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.de.resx b/ImageResizer/src/ImageResizer/Properties/Resources.de.resx
new file mode 100644
index 000000000000..3dea8eedc9cf
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.de.resx
@@ -0,0 +1,346 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Über
+
+
+ Neue Größe erstellen
+
+
+ Entfernen
+
+
+ Komprimierung
+
+
+ Ausweich-Komprimierung:
+
+
+ Datei
+
+
+ Dateiname:
+
+
+ Ursprungsdateiname
+
+
+ Größen-Name
+
+
+ Ausgewählte Breite
+
+
+ Ausgewählte Höhe
+
+
+ Ursprüngliche Breite (Pixel)
+
+
+ Ursprüngliche Höhe (Pixel)
+
+
+ Die folgenden Parameter können verwendet werden.
+
+
+ JPEG-Qualitätsstufe:
+
+
+ Ursprüngliches Änderungsdatum verwenden
+
+
+ PNG Interlacing
+
+
+ Größen
+
+
+ TIFF Komprimierung:
+
+
+ Erweiterte Optionen
+
+
+ Alle Dateien
+
+
+ Abbrechen
+
+
+ © 2019 Brice Lambson. Alle Rechte vorbehalten.
+
+
+ Image Resizer für Windows
+
+
+ (auto)
+
+
+ Wähle eine Größe
+
+
+ Benutzerdefiniert
+
+
+ Ignoriere die _Ausrichtung von Bildern
+
+
+ Skaliere deine Bilder
+
+
+ Skaliere die Originalbilder (erstellt keine Kopien)
+
+
+ Größe ände_rn
+
+
+ Erweiterte Optionen...
+
+
+ Mache Bilder kleiner aber nicht größer
+
+
+ Groß
+
+
+ Mittel
+
+
+ OK
+
+
+ Handy
+
+
+ Alle Bilddateien
+
+
+ (Standard)
+
+
+ Aus
+
+
+ An
+
+
+ Bilder werden skaliert...
+
+
+ Stop
+
+
+ Etwa {0} Stunde, {1} Minute verbleibend.
+
+
+ Etwa {0} Stunde, {1} Minuten verbleibend.
+
+
+ Etwa {0} Stunden, {1} Minute verbleibend.
+
+
+ Etwa {0} Stunden, {1} Minuten verbleibend.
+
+
+ Etwa {1} Minute, {2} Sekunde verbleibend.
+
+
+ Etwa {1} Minute, {2} Sekunden verbleibend.
+
+
+ Etwa {1} Minuten, {2} Sekunde verbleibend.
+
+
+ Etwa {1} Minuten, {2} Sekunden verbleibend.
+
+
+ Etwa {2} Sekunde verbleibend.
+
+
+ Etwa {2} Sekunden verbleibend.
+
+
+ Füllen
+
+
+ füllt
+
+
+ passend
+
+
+ passt in
+
+
+ strecken
+
+
+ strecken bis
+
+
+ Zentimeter
+
+
+ Inch
+
+
+ Prozent
+
+
+ Pixel
+
+
+ Schließen
+
+
+ Kann die Größe des folgenden Bildes nicht ändern
+
+
+ Klein
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Standard)
+
+
+ LZW
+
+
+ Keiner
+
+
+ RLE
+
+
+ Zip
+
+
+ Wert muss zwischen '{0}' und '{1}' liegen.
+
+
+
+ Version
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.es.resx b/ImageResizer/src/ImageResizer/Properties/Resources.es.resx
new file mode 100644
index 000000000000..582acc241301
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.es.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Acerca de...
+
+
+ Crear nuevo tamaño
+
+
+ Eliminar
+
+
+ Codificación
+
+
+ Codificador de _respaldo
+
+
+ Fichero
+
+
+ _Nombre de fichero
+
+
+ Nombre de fichero original
+
+
+ Nombre de tamaño
+
+
+ Ancho seleccionado
+
+
+ Altura deseada
+
+
+ Anchura real (pixeles)
+
+
+ Altura actual (píxeles)
+
+
+ Los siguientes parámetros están disponibles.
+
+
+ Calidad _JPEG:
+
+
+ _Usar fecha original modificada
+
+
+ Entrelazado _PNG:
+
+
+ Tamaños
+
+
+ Compresión _TIFF:
+
+
+ Opciones avanzadas
+
+
+ Todos los ficheros
+
+
+ Cancelar
+
+
+ © 2019 Brice Lambson. Todos los derechos reservados.
+
+
+ Image Resizer para Windows
+
+
+ (auto)
+
+
+ _Escoge un tamaño.
+
+
+ Personalizado
+
+
+ Ign_orar la orientación
+
+
+ Redimensionar las imagenes
+
+
+ R_edimensionar las imágenes originales (sin copia)
+
+
+ _Redimensionar
+
+
+ Opciones avanzadas...
+
+
+ Solo _encoger, no agrandar
+
+
+ Grande
+
+
+ Mediano
+
+
+ Aceptar
+
+
+ Teléfono
+
+
+ Todas las imágenes
+
+
+ (Por defecto)
+
+
+ Desactivado
+
+
+ Activado
+
+
+ Redimensionando imágenes...
+
+
+ _Parar
+
+
+ Falta {0} hora, {1} minuto
+
+
+ Falta {0} hora, {1} minutos
+
+
+ Faltan {0} horas, {1} minuto
+
+
+ Faltan {0} horas, {1} minutos
+
+
+ Falta {1} minuto, {2} segundo
+
+
+ Falta {1} minuto, {2} segundos
+
+
+ Faltan {1} minutos, {2} segundo
+
+
+ Faltan {1} minutos, {2} segundos
+
+
+ Falta {2} segundo
+
+
+ Faltan {2} segundos
+
+
+ Llenar
+
+
+ llena
+
+
+ Ajustar
+
+
+ se ajusta
+
+
+ Estirar
+
+
+ Estira a
+
+
+ Centímetros
+
+
+ Pulgadas
+
+
+ Porcentaje
+
+
+ Píxeles
+
+
+ Cerrar
+
+
+ No se pueden redimensionar las imágenes
+
+
+ Pequeño
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Por defecto)
+
+
+ LZW
+
+
+ Ninguno
+
+
+ RLE
+
+
+ Zip
+
+
+ El valor debe estar entre '{0}' y '{1}'.
+
+
+ Versión
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.eu-ES.resx b/ImageResizer/src/ImageResizer/Properties/Resources.eu-ES.resx
new file mode 100644
index 000000000000..84867840df8d
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.eu-ES.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Honi buruz
+
+
+ Tamaina berria sortu
+
+
+ Ezabatu
+
+
+ Kodifikazioa
+
+
+ _Badaezpadako kodifikazioa
+
+
+ Fitxategia
+
+
+ _Fitxategi izena
+
+
+ Jatorrizko fitxategi izena
+
+
+ Tamaina izena
+
+
+ Aukeratutako zabalera
+
+
+ Hautatutako altuera
+
+
+ Benetako zabalera (pixelak)
+
+
+ Benetako altuera (pixelak)
+
+
+ Parametro hauek erabilgarri.
+
+
+ _JPEG kalitate maila:
+
+
+ Erabili jatorrizko data _aldatuta
+
+
+ _PNG interlacing:
+
+
+ Taminak
+
+
+ _TIFF konpresioa:
+
+
+ Aukera Aurreratuak
+
+
+ Fitxategi Guztiak
+
+
+ Ezeztatu
+
+
+ © 2019 Brice Lambson. Eskubide guztiak babestuak.
+
+
+ Image Resizer Windowserako
+
+
+ (auto)
+
+
+ _Aukeratu tamaina.
+
+
+ Neurrirakoa
+
+
+ Orientazioari ez-ikusi egin
+
+
+ Tamainaz aldatu
+
+
+ Jatorrizko irudiei tamaina aldatu (kopiarik gabe)
+
+
+ _Tamaina aldatu
+
+
+ Aukera aurreratuak...
+
+
+ _Txikitu irudiak, inoiz ez handitu
+
+
+ Handia
+
+
+ Ertaina
+
+
+ Ados
+
+
+ Telefonoa
+
+
+ Irudi guztiak
+
+
+ (Lehenetsia)
+
+
+ Ezgaituta
+
+
+ Gaituta
+
+
+ Tamainaz aldatzen...
+
+
+ _Gelditu
+
+
+ Ordu {0}, minutu {1} faltan
+
+
+ Ordu {0}, {1} minutu faltan
+
+
+ {0} ordu, minutu {1} faltan
+
+
+ {0} ordu, {1} minutu faltan.
+
+
+ Minutu {1}, segundu {2} faltan.
+
+
+ Minutu {1}, {2} segundu faltan.
+
+
+ {1} minutu, segundu {2} faltan.
+
+
+ {1} minutu, {2} segundu faltan.
+
+
+ Segundu {2} faltan.
+
+
+ {2} segundu faltan.
+
+
+ Bete
+
+
+ betetzen du
+
+
+ Egokitu
+
+
+ egokitzen da
+
+
+ Luzatu
+
+
+ luzatzen da
+
+
+ Zentimetroak
+
+
+ Hazbete
+
+
+ Ehunekoa
+
+
+ Pixelak
+
+
+ Itxi
+
+
+ Irudiak ezin dira tamainaz aldatu
+
+
+ Txikia
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Lehenetsia)
+
+
+ LZW
+
+
+ Bat erez
+
+
+ RLE
+
+
+ Zip
+
+
+ Balioa '{0}' eta '{1}' artean behar du
+
+
+ Bertsioa
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.fr.resx b/ImageResizer/src/ImageResizer/Properties/Resources.fr.resx
new file mode 100644
index 000000000000..dd175afbbf69
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.fr.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ À propos
+
+
+ Créer une nouvelle taille
+
+
+ Effacer
+
+
+ Encodage
+
+
+ Encodeur
+
+
+ Fichier
+
+
+ Nom de fichier
+
+
+ Nom de fichier d'origine
+
+
+ Nom de la taille
+
+
+ Largeur sélectionnée
+
+
+ Hauteur sélectionnée
+
+
+ Largeur réelle (pixels)
+
+
+ Hauteur réelle (pixels)
+
+
+ Les paramètres suivants peuvent être utilisés.
+
+
+ JPEG : Qualité
+
+
+ Conserver la date de dernière modification d'origine.
+
+
+ PNG : Entrelacement
+
+
+ Tailles
+
+
+ TIFF : Compression
+
+
+ Paramètres avancés
+
+
+ Tous les Fichiers
+
+
+ Annuler
+
+
+ © 2019 Brice Lambson. Tous droits réservés.
+
+
+ Image Resizer pour Windows
+
+
+ (auto)
+
+
+ Sélectionner une taille
+
+
+ Personnalisé
+
+
+ Ignorer l'orientation de l'image
+
+
+ Redimensionnez vos images
+
+
+ Redimensionner les originaux (ne crée pas de copies)
+
+
+ Redimensionner
+
+
+ Paramètres avancés
+
+
+ Le cas échéant, ne pas agrandir les images.
+
+
+ Grand
+
+
+ Moyen
+
+
+ OK
+
+
+ Téléphone
+
+
+ Toutes les images
+
+
+ (Par défaut)
+
+
+ Off
+
+
+ On
+
+
+ Redimensionnement en cours...
+
+
+ Stop
+
+
+ Il reste environ {0} heure, {1} minute.
+
+
+ Il reste environ {0} heure, {1} minutes.
+
+
+ Il reste environ {0} heures, {1} minute.
+
+
+ Il reste environ {0} heures, {1} minutes.
+
+
+ Il reste environ {1} minute, {2} seconde.
+
+
+ Il reste environ {1} minute, {2} secondes.
+
+
+ Il reste environ {1} minutes, {2} seconde.
+
+
+ Il reste environ {1} minutes, {2} secondes.
+
+
+ Il reste environ {2} seconde.
+
+
+ Il reste environ {2} secondes.
+
+
+ Imposer
+
+
+ impose
+
+
+ Adapter
+
+
+ ratio respecté dans
+
+
+ Etirer
+
+
+ étirer jusqu'à
+
+
+ Centimètres
+
+
+ Pouces
+
+
+ Pourcent
+
+
+ Pixels
+
+
+ Fermer
+
+
+ Redimensionnement des images impossible
+
+
+ Petit
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Par défaut)
+
+
+ LZW
+
+
+ Aucun
+
+
+ RLE
+
+
+ Zip
+
+
+ La valeur doit être entre '{0}' et '{1}'.
+
+
+ Version
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.he.resx b/ImageResizer/src/ImageResizer/Properties/Resources.he.resx
new file mode 100644
index 000000000000..da3f69e9580b
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.he.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ אודות
+
+
+ צור גודל חדש
+
+
+ מחק
+
+
+ קידוד
+
+
+ מקודד נסיגה:
+
+
+ קובץ
+
+
+ שם קובץ:
+
+
+ שם קובץ מקורי:
+
+
+ שם גודל
+
+
+ רוחב נבחר
+
+
+ גובה נבחר
+
+
+ רוחב אפקטיבי (פיקסלים)
+
+
+ גובה אפקטיבי (פיקסלים)
+
+
+ הפרמטרים הבאים יכולים להיות בשימוש.
+
+
+ רמת איכות JPEG
+
+
+ השתמש בתאריך השינוי המקורי
+
+
+ תשזורת PNG:
+
+
+ גדלים
+
+
+ דחיסת TIFF:
+
+
+ מתקדם
+
+
+ כל הקבצים
+
+
+ בטל
+
+
+ © 2019 ברייס למבסון. כל הזכויות שמורות.
+
+
+ משנה גודל תמונות לווינדוס
+
+
+ (אוטומטי)
+
+
+ בחר גודל.
+
+
+ מותאם אישית
+
+
+ התעלם מהאוריאנטציה של התמונות
+
+
+ שנה את גודל התמונות שלך
+
+
+ שנה את גודל התמונות המקוריות (אל תיצור העתקים)
+
+
+ שנה גודל
+
+
+ מתקדם
+
+
+ הקטן את התמונות, אך אל תגדיל אותן
+
+
+ גדול
+
+
+ בינוני
+
+
+ אישור
+
+
+ טלפון
+
+
+ כל קבצי התמונות
+
+
+ (ברירת מחדל)
+
+
+ כבוי
+
+
+ מופעל
+
+
+ שנה את גודל התמונות...
+
+
+ עצור
+
+
+ נותרה עוד כ{0} שעה ו{1} דקה.
+
+
+ נותרה עוד כ{0} שעה ו{1} דקות.
+
+
+ נותרה עוד כ{0} שעות ו{1} דקה.
+
+
+ נותרה עוד כ{0} שעות ו{1} דקות.
+
+
+ נותרה עוד כ{1} דקה ו{2} שניה.
+
+
+ נותרה עוד כ{1} דקה ו{2} שניות.
+
+
+ נותרה עוד כ{1} דקות ו{2} שניה.
+
+
+ נותרה עוד כ{1} דקות ו{2} שניות.
+
+
+ נותרה עוד כ{2} שניה.
+
+
+ נותרה עוד כ{2} שניות.
+
+
+ התאם
+
+
+ מתאים
+
+
+ התאם
+
+
+ מתאים בתוך
+
+
+ מתח
+
+
+ מתח ל
+
+
+ סנטימטרים
+
+
+ אינצ'ים
+
+
+ אחוז
+
+
+ פיקסלים
+
+
+ סגור
+
+
+ לא ניתן לשנות את גודל התמונות הבאות
+
+
+ קטן
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (ברירת מחדל)
+
+
+ LZW
+
+
+ כלום
+
+
+ RLE
+
+
+ Zip
+
+
+ הערך חייב להיות בין '{0}' ו-'{1}'.
+
+
+ גרסא
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.hu.resx b/ImageResizer/src/ImageResizer/Properties/Resources.hu.resx
new file mode 100644
index 000000000000..711a60f8c3af
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.hu.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Névjegy
+
+
+ Új méret készítése
+
+
+ Törlés
+
+
+ Kódolás
+
+
+ Tartalék kódolás:
+
+
+ Fájl
+
+
+ Fájlnév:
+
+
+ Eredeti fájlnév
+
+
+ Méret név
+
+
+ Kiválasztott szélesség
+
+
+ Kiválasztott magasság
+
+
+ Jelenlegi szélesség (pixelben)
+
+
+ Jelenlegi magasság (pixelben)
+
+
+ A következő paraméterek használhatók.
+
+
+ JPEG minőség szint:
+
+
+ Eredeti módosítási dátum megtartása.
+
+
+ PNG váltósorosság:
+
+
+ Méretek
+
+
+ TIFF tömörítés:
+
+
+ Haladó beállítások
+
+
+ Minden fájl
+
+
+ Mégse
+
+
+ © 2019 Brice Lambson. Minden jog fenntartva.
+
+
+ Képméretező Windowsra
+
+
+ (auto)
+
+
+ Válassz méretet.
+
+
+ Egyedi
+
+
+ Képek tájolásának figyelmen kívül hagyása
+
+
+ Képek átméretezése
+
+
+ Eredeti képek átméretezése (nem készül másolat)
+
+
+ Átméretezés
+
+
+ Haladó beállítások...
+
+
+ Képek kicsinyítése, de nem nagyítása
+
+
+ Nagy
+
+
+ Közepes
+
+
+ Rendben
+
+
+ Telefon
+
+
+ Minden kép fájl
+
+
+ (Alapértelmezett)
+
+
+ Ki
+
+
+ Be
+
+
+ Képek átméretezése...
+
+
+ Állj
+
+
+ Körülbelül {0} óra {1} perc van hátra.
+
+
+ Körülbelül {0} óra {1} perc van hátra.
+
+
+ Körülbelül {0} óra {1} perc van hátra.
+
+
+ Körülbelül {0} óra {1} perc van hátra.
+
+
+ Körülbelül {1} perc {2} másodperc van hátra.
+
+
+ Körülbelül {1} perc {2} másodperc van hátra.
+
+
+ Körülbelül {1} perc {2} másodperc van hátra.
+
+
+ Körülbelül {1} perc {2} másodperc van hátra.
+
+
+ Körülbelül {2} másodperc van hátra.
+
+
+ Körülbelül {2} másodperc van hátra.
+
+
+ Kitöltés
+
+
+ kitöltés
+
+
+ Illesztés
+
+
+ illesztés
+
+
+ Nyújtás
+
+
+ nyújtás
+
+
+ Centiméterre
+
+
+ Hüvelykre
+
+
+ Százalékra
+
+
+ Pixelre
+
+
+ Bezár
+
+
+ A következő képeket nem sikerült átméretezni
+
+
+ Kicsi
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Alapértelmezett)
+
+
+ LZW
+
+
+ Nincs
+
+
+ RLE
+
+
+ Zip
+
+
+ Az értéknek '{0}' és '{1}' között kell lennie.
+
+
+ Verzió
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.it.resx b/ImageResizer/src/ImageResizer/Properties/Resources.it.resx
new file mode 100644
index 000000000000..6d022d200588
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.it.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Informazioni su...
+
+
+ Crea una nuova dimensione
+
+
+ Elimina
+
+
+ Codifica
+
+
+ _Codificatore Fallback:
+
+
+ File
+
+
+ _Nome file:
+
+
+ Nome file originale
+
+
+ Nome dimensione
+
+
+ Larghezza selezionata
+
+
+ Altezza selezionata
+
+
+ Larghezza attuale (pixel)
+
+
+ Altezza attuale (pixel)
+
+
+ Possono essere usati i seguenti parametri.
+
+
+ _Qualità JPEG:
+
+
+ _Usa la data originale modificata
+
+
+ _Interlacciamento PNG:
+
+
+ Dimensioni
+
+
+ _Compressione TIFF:
+
+
+ Opzioni avanzate
+
+
+ Tutti i file
+
+
+ Annulla
+
+
+ © 2019 Brice Lambson. Tutti i diritti riservati.
+
+
+ Image Resizer per Windows
+
+
+ (auto)
+
+
+ _Scegli una dimensione.
+
+
+ A scelta
+
+
+ Ignora l'orientamento delle immagini
+
+
+ Ridimensiona le tue immagini
+
+
+ Ridimensiona le immagini originali (non creare copie)
+
+
+ Ridimensiona
+
+
+ Opzioni avanzate...
+
+
+ _Crea immagini più piccole ma non più grandi
+
+
+ Grande
+
+
+ Media
+
+
+ OK
+
+
+ Telefono
+
+
+ Tutti i file immagine
+
+
+ (Predefinito)
+
+
+ Off
+
+
+ On
+
+
+ Sto ridimensionando le immagini...
+
+
+ Stop
+
+
+ Circa {0} ora, {1} minuto rimanenti.
+
+
+ Circa {0} ora, {1} minuti rimanenti.
+
+
+ Circa {0} ore, {1} minuto rimanenti.
+
+
+ Circa {0} ore, {1} minuti rimanenti.
+
+
+ Circa {1} minuto, {2} secondo rimanenti.
+
+
+ Circa {1} minuto, {2} secondi rimanenti.
+
+
+ Circa {1} minuti, {2} secondo rimanenti.
+
+
+ Circa {1} minuti, {2} secondi rimanenti.
+
+
+ Circa {2} secondo rimanente.
+
+
+ Circa {2} secondi rimanenti.
+
+
+ Riempi
+
+
+ riempie
+
+
+ Adatta
+
+
+ entro
+
+
+ Deforma
+
+
+ deforma
+
+
+ Centimetri
+
+
+ Pollici
+
+
+ Percento
+
+
+ Pixel
+
+
+ Chiudi
+
+
+ Impossibile ridimensionare le seguenti immagini
+
+
+ Piccola
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Predefinito)
+
+
+ LZW
+
+
+ Nessuno
+
+
+ RLE
+
+
+ Zip
+
+
+ Il valore deve essere compreso tra '{0}' e '{1}'.
+
+
+ Versione
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.nb-NO.resx b/ImageResizer/src/ImageResizer/Properties/Resources.nb-NO.resx
new file mode 100644
index 000000000000..954e83f0231b
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.nb-NO.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Om
+
+
+ Lag ny størrelse
+
+
+ Slett
+
+
+ Koding
+
+
+ _Fallback encoder:
+
+
+ Fil
+
+
+ _Filnavn:
+
+
+ Originalt filnavn
+
+
+ Navn på størrelse
+
+
+ Valgte bredde
+
+
+ Valgte høyde
+
+
+ Faktisk bredde (piksler)
+
+
+ Faktisk høyde (piksler)
+
+
+ Følgende parametre kan brukes.
+
+
+ _JPEG kvalitetsnivå
+
+
+ _Bruk original endringsdato
+
+
+ _PNG interlasering:
+
+
+ Størrelser
+
+
+ _TIFF komprimering
+
+
+ Avanserte alternativer
+
+
+ Alle filer
+
+
+ Avbryt
+
+
+ © 2019 Brice Lambson. Alle rettigheter er reservert
+
+
+ Image Resizer for Windows
+
+
+ (auto)
+
+
+ _Velg en størrelse.
+
+
+ Tilpasset
+
+
+ Ign_orer bildes retning
+
+
+ Endre bildestørrelse
+
+
+ Endr_e originalbildet (ikke lag kopi)
+
+
+ _Endre størrelse
+
+
+ Avanserte alternativer...
+
+
+ _Lag bildene mindre, men ikke større
+
+
+ Stor
+
+
+ Medium
+
+
+ OK
+
+
+ Telefon
+
+
+ Alle bildefiler
+
+
+ (Standard)
+
+
+ Av
+
+
+ På
+
+
+ Endrer størrelse på bildene...
+
+
+ _Stopp
+
+
+ Omtrent {0} time, {1} minutt gjenstår.
+
+
+ Omtrent {0} time, {1} minutter gjenstår.
+
+
+ Omtrent {0} timer, {1} minutt gjenstår.
+
+
+ Omtrent {0} timer, {1} minutter gjenstår.
+
+
+ Omtrent {0} minutt, {1} sekund gjenstår.
+
+
+ Omtrent {0} minutt, {1} sekunder gjenstår.
+
+
+ Omtrent {0} minutter, {1} sekund gjenstår.
+
+
+ Omtrent {0} minutter, {1} sekunder gjenstår.
+
+
+ Omtrent {2} sekund gjenstår.
+
+
+ Omtrent {2} sekunder gjenstår.
+
+
+ Fyll
+
+
+ fyller
+
+
+ Passer
+
+
+ passer innenfor
+
+
+ Stekk
+
+
+ strekkes til
+
+
+ Centimeter
+
+
+ Tommer
+
+
+ Prosent
+
+
+ Piksler
+
+
+ Lukk
+
+
+ Kan ikke endre størrelse på følgende bilder
+
+
+ Liten
+
+
+ CCIT3
+
+
+ CCIT4
+
+
+ (Standard)
+
+
+ LZW
+
+
+ Ingen
+
+
+ RLE
+
+
+ Zip
+
+
+ Verdi må være mellom '{0}' og '{1}'.
+
+
+ Versjon
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.nl.resx b/ImageResizer/src/ImageResizer/Properties/Resources.nl.resx
new file mode 100644
index 000000000000..b7b042a1c391
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.nl.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Over
+
+
+ Nieuw afbeeldingsformaat invoeren
+
+
+ Wissen
+
+
+ Compressie
+
+
+ _Dodge compressie:
+
+
+ Bestand
+
+
+ _Bestandsnaam:
+
+
+ Originele bestandsnaam
+
+
+ Naam van het formaat
+
+
+ Geselecteerde breedte
+
+
+ Geselecteerde hoogte
+
+
+ Werkelijke breedte (pixels)
+
+
+ Werkelijke hoogte (pixels)
+
+
+ De volgende parameters kunnen worden gebruikt:
+
+
+ _JPEG kwaliteitsniveau:
+
+
+ _Gebruik de originele wijzigingsdatum
+
+
+ _PNG interliniëring:
+
+
+ Formaten
+
+
+ _TIFF compressie:
+
+
+ Geavanceerde instellingen
+
+
+ Alle bestanden
+
+
+ Annuleren
+
+
+ © 2019 Brice Lambson. Alle rechten voorbehouden.
+
+
+ Fotovergroter/verkleiner voor Windows
+
+
+ (auto)
+
+
+ _Selecteer een afmeting.
+
+
+ Aangepast
+
+
+ Negeer de _oriëntering van de afbeelding
+
+
+ Afbeeldingsformaat wijzigen
+
+
+ Wijzig de originele _afbeeldingen (maak geen kopieën)
+
+
+ _Verkleinen/vergroten
+
+
+ Geavanceerde instellingen
+
+
+ Verklein afbeeldingen, vergroot niet
+
+
+ Groot
+
+
+ Middel
+
+
+ OK
+
+
+ Miniatuur
+
+
+ Alle afbeeldingsbestanden
+
+
+ (Standaard)
+
+
+ Uit
+
+
+ Aan
+
+
+ Verklein/vergroot foto's...
+
+
+ _Stop
+
+
+ Ongeveer {0} uur en {1} minuut resterend.
+
+
+ Ongeveer {0} uur en {1} minuten resterend.
+
+
+ Ongeveer {0} uren en {1} minuut resterend.
+
+
+ Ongeveer {0} uren en {1} minuten resterend.
+
+
+ Ongeveer {1} minuut en {2} seconde resterend.
+
+
+ Ongeveer {1} minuut en {2} seconden resterend.
+
+
+ Ongeveer {1} minuten en {2} seconde resterend.
+
+
+ Ongeveer {1} minuten en {2} seconden resterend.
+
+
+ Ongeveer {2} seconde resterend.
+
+
+ Ongeveer {2} seconden resterend.
+
+
+ Uitvullen
+
+
+ vult uit
+
+
+ Passend
+
+
+ past binnen
+
+
+ Uitrekken
+
+
+ rekt uit naar
+
+
+ Centimeters
+
+
+ Duimen
+
+
+ Procent
+
+
+ Pixels
+
+
+ Sluiten
+
+
+ De volgende afbeeldingen kunnen niet worden gewijzigd
+
+
+ Klein
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Standaard)
+
+
+ LZW
+
+
+ Geen
+
+
+ RLE
+
+
+ Zip
+
+
+ Waarde moet liggen tussen '{0}' en '{1}'.
+
+
+ Versie
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.pl.resx b/ImageResizer/src/ImageResizer/Properties/Resources.pl.resx
new file mode 100644
index 000000000000..157542ecd995
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.pl.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ O programie
+
+
+ Utwórz nowy rozmiar
+
+
+ Usuń
+
+
+ Kodowanie
+
+
+ Usterka kodera:
+
+
+ Plik
+
+
+ Nazwa pliku:
+
+
+ Oryginalna nazwa pliku
+
+
+ Nazwa rozmiaru
+
+
+ Wybierz szerokość
+
+
+ Wybierz wysokość
+
+
+ Obecna szerokość (w pikselach)
+
+
+ Obecna wysokość (w pikselach)
+
+
+ Następujące parametry mogą zostać użyte.
+
+
+ Stopień jakości JPG
+
+
+ Użyj oryginalnej daty modyfikacji
+
+
+ Przeplot PNG:
+
+
+ Rozmiary
+
+
+ Kompresja TIFF:
+
+
+ Ustawienia zaawansowane
+
+
+ Wszystkie pliki
+
+
+ Anuluj
+
+
+ © 2019 Brice Lambson. Wszystkie prawa zastrzeżone.
+
+
+ Image Resizer dla Windows
+
+
+ (auto)
+
+
+ Wybierz rozmiar
+
+
+ Niestandardowy
+
+
+ Ignoruj orientację
+
+
+ Zmień rozmiar obrazów
+
+
+ Zmień rozmiar obrazów (nie twórz kopii)
+
+
+ Zmień rozmiar
+
+
+ Ustawienia zaawansowane...
+
+
+ Tylko zmniejsz rozmiar, nie powiększaj
+
+
+ Duży
+
+
+ Średni
+
+
+ OK
+
+
+ Telefon
+
+
+ Wszystkie obrazy
+
+
+ (Domyślne)
+
+
+ Wył.
+
+
+ Wł.
+
+
+ Zmieniam rozmiar zdjęć...
+
+
+ Zatrzymaj
+
+
+ Pozostało godzin {0}, minut {1}
+
+
+ Pozostało godzin {0}, minut {1}
+
+
+ Pozostało godzin {0}, minut {1}
+
+
+ Pozostało godzin {0}, minut {1}
+
+
+ Pozostało minut {1}, sekund {2}
+
+
+ Pozostało minut {1}, sekund {2}
+
+
+ Pozostało minut {1}, sekund {2}
+
+
+ Pozostało minut {1}, sekund {2}
+
+
+ Pozostało sekund {2}
+
+
+ Pozostało sekund {2}
+
+
+ Wypełnij
+
+
+ wypełnia
+
+
+ Dopasuj
+
+
+ Dopasuj do
+
+
+ Rozciągnij
+
+
+ Rozciągnij do
+
+
+ Centymetrów
+
+
+ Cali
+
+
+ Procent
+
+
+ Pikseli
+
+
+ Zamknij
+
+
+ Nie można zmienić rozmiaru zdjęć
+
+
+ Mały
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Domyślna)
+
+
+ LZW
+
+
+ Brak
+
+
+ RLE
+
+
+ Zip
+
+
+ Wartość musi być pomiędzy '{0}' i '{1}'.
+
+
+ Wersja
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.pt-BR.resx b/ImageResizer/src/ImageResizer/Properties/Resources.pt-BR.resx
new file mode 100644
index 000000000000..97f830e365cf
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.pt-BR.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Sobre
+
+
+ Criar novo tamanho
+
+
+ Apagar
+
+
+ Codificação
+
+
+ _Fallback encoder:
+
+
+ Arquivo
+
+
+ Nome do arquivo:
+
+
+ Nome original
+
+
+ Nome do tamanho
+
+
+ Largura selecionada
+
+
+ Altura selecionada
+
+
+ Largura atual (pixels)
+
+
+ Altura atual (pixels)
+
+
+ O seguintes parâmetros podem ser utilizados.
+
+
+ _JPEG nível de qualidade:
+
+
+ _Utilizar data de modificação original
+
+
+ Entrelaçamento _PNG:
+
+
+ Tamanhos
+
+
+ Compressão _TIFF:
+
+
+ Opções Avançadas
+
+
+ Todos os arquivos
+
+
+ Cancelar
+
+
+ © 2019 Brice Lambson. Todos os direitos reservados.
+
+
+ Redimensionar Imagens para Windows
+
+
+ (auto)
+
+
+ _Selecione um tamanho.
+
+
+ Personalizado
+
+
+ Ign_orar a orientação das imagens
+
+
+ Redimensione suas imagens
+
+
+ R_edimensionar imagens originais (não criar cópias)
+
+
+ _Redimensionar
+
+
+ Opções Avançadas...
+
+
+ Reduzir i_magens mas não aumentar
+
+
+ Grande
+
+
+ Médio
+
+
+ OK
+
+
+ Telefone
+
+
+ Todos os arquivos de Imagens
+
+
+ (Padrão)
+
+
+ Desligado
+
+
+ Ligado
+
+
+ Redimensionar suas imagens...
+
+
+ Parar
+
+
+ Aproximadamente {0} hora, {1} minuto restante.
+
+
+ Aproximadamente {0} hora, {1} minutos restantes.
+
+
+ Aproximadamente {0} horas, {1} minuto restante.
+
+
+ Aproximadamente {0} horas, {1} minutos restantes.
+
+
+ Aproximadamente {1} minuto, {2} segundo restante.
+
+
+ Aproximadamente {1} minuto, {2} segundos restantes.
+
+
+ Aproximadamente {1} minutos, {2} segundo restante.
+
+
+ Aproximadamente {1} minutos, {2} segundos restantes.
+
+
+ Aproximadamente {2} segundo restante.
+
+
+ Aproximadamente {2} segundos restantes.
+
+
+ Preencher
+
+
+ preenche
+
+
+ Encaixar
+
+
+ encaixar dentro
+
+
+ Esticar
+
+
+ esticar para
+
+
+ Centímetros
+
+
+ Polegadas
+
+
+ Percentual
+
+
+ Pixels
+
+
+ Fechar
+
+
+ Não posso redimensionar as seguintes imagens
+
+
+ Pequeno
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Padrão)
+
+
+ LZW
+
+
+ Nenhum
+
+
+ RLE
+
+
+ Zip
+
+
+ Valor deve ser entre '{0}' e '{1}'.
+
+
+ Versão
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.resx b/ImageResizer/src/ImageResizer/Properties/Resources.resx
new file mode 100644
index 000000000000..1c345caae52e
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ About
+
+
+ Create a new size
+
+
+ Delete
+
+
+ Encoding
+
+
+ _Fallback encoder:
+
+
+ File
+
+
+ _Filename:
+
+
+ Original filename
+
+
+ Size name
+
+
+ Selected width
+
+
+ Selected height
+
+
+ Actual width (pixels)
+
+
+ Actual height (pixels)
+
+
+ The following parameters can be used.
+
+
+ _JPEG quality level:
+
+
+ _Use original date modified
+
+
+ _PNG interlacing:
+
+
+ Sizes
+
+
+ _TIFF compression:
+
+
+ Advanced Options
+
+
+ All Files
+
+
+ Cancel
+
+
+ © 2019 Brice Lambson. All rights reserved.
+
+
+ Image Resizer for Windows
+
+
+ (auto)
+
+
+ _Select a size.
+
+
+ Custom
+
+
+ Ign_ore the orientation of pictures
+
+
+ Resize your pictures
+
+
+ R_esize the original pictures (don't create copies)
+
+
+ _Resize
+
+
+ Advanced options...
+
+
+ _Make pictures smaller but not larger
+
+
+ Large
+
+
+ Medium
+
+
+ OK
+
+
+ Phone
+
+
+ All Picture Files
+
+
+ (Default)
+
+
+ Off
+
+
+ On
+
+
+ Resizing your pictures...
+
+
+ _Stop
+
+
+ About {0} hour, {1} minute remaining.
+
+
+ About {0} hour, {1} minutes remaining.
+
+
+ About {0} hours, {1} minute remaining.
+
+
+ About {0} hours, {1} minutes remaining.
+
+
+ About {1} minute, {2} second remaining.
+
+
+ About {1} minute, {2} seconds remaining.
+
+
+ About {1} minutes, {2} second remaining.
+
+
+ About {1} minutes, {2} seconds remaining.
+
+
+ About {2} second remaining.
+
+
+ About {2} seconds remaining.
+
+
+ Fill
+
+
+ fills
+
+
+ Fit
+
+
+ fits within
+
+
+ Stretch
+
+
+ stretches to
+
+
+ Centimeters
+
+
+ Inches
+
+
+ Percent
+
+
+ Pixels
+
+
+ Close
+
+
+ Can't resize the following pictures
+
+
+ Small
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Default)
+
+
+ LZW
+
+
+ None
+
+
+ RLE
+
+
+ Zip
+
+
+ Value must be between '{0}' and '{1}'.
+
+
+ Version
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.ru.resx b/ImageResizer/src/ImageResizer/Properties/Resources.ru.resx
new file mode 100644
index 000000000000..78cbe618c5f0
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.ru.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ О программе
+
+
+ Создать новый размер
+
+
+ Удалить
+
+
+ Кодирование
+
+
+ Резервный кодировщик:
+
+
+ Файл
+
+
+ Имя файла:
+
+
+ Исходное имя файла:
+
+
+ Имя размера
+
+
+ Выбранная ширина
+
+
+ Выбранная высота
+
+
+ Текущая ширина (пикселей)
+
+
+ Текущая высота (пикселей)
+
+
+ Могут использоваться следующие параметры.
+
+
+ Качество JPEG:
+
+
+ Использовать исходную дату изменения
+
+
+ Интерлейсинг PNG:
+
+
+ Размеры
+
+
+ Сжатие TIFF:
+
+
+ Расширенные настройки
+
+
+ Все файлы
+
+
+ отменить
+
+
+ © 2019 Brice Lambson. Все права защищены.
+
+
+ Image Resizer для Windows
+
+
+ (авто)
+
+
+ _Выберите размер.
+
+
+ изготовленный на заказ
+
+
+ игнорировать ориентацию фото
+
+
+ Изменить размер ваших фотографий
+
+
+ Изменять оригинальные фотографии (не создавать копии)
+
+
+ Изменить
+
+
+ Расширенные настройки...
+
+
+ Делайте картинки меньше, но не больше
+
+
+ большой
+
+
+ Средняя
+
+
+ Хорошо
+
+
+ Телефон
+
+
+ Все файлы изображений
+
+
+ По умолчанию
+
+
+ Отключено
+
+
+ Включено
+
+
+ Изменение размеров изображений...
+
+
+ Остановить
+
+
+ Осталось около {0} часов, {1} минут.
+
+
+ Осталось около {0} часов, {1} минут.
+
+
+ Осталось около {0} часов, {1} минут.
+
+
+ Осталось около {0} часов, {1} минут.
+
+
+ Осталось около {1} минут, {2} секунд.
+
+
+ Осталось около {1} минут, {2} секунд.
+
+
+ Осталось около {1} минут, {2} секунд.
+
+
+ Осталось около {1} минут, {2} секунд.
+
+
+ Осталось около {2} секунд.
+
+
+ Осталось около {2} секунд.
+
+
+ заполнить
+
+
+ заливка
+
+
+ Поместиться
+
+
+ вписывается в
+
+
+ Растянуть
+
+
+ растянуто до
+
+
+ сантиметров
+
+
+ дюймов
+
+
+ Процентов
+
+
+ Пиксели
+
+
+ Закрыть
+
+
+ Не удается изменить размер следующих изображений
+
+
+ Маленький
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ По умолчанию
+
+
+ LZW
+
+
+ Нет
+
+
+ RLE
+
+
+ Zip
+
+
+ Значение должно быть от '{0}' до '{1}'.
+
+
+ Версия
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.sk.resx b/ImageResizer/src/ImageResizer/Properties/Resources.sk.resx
new file mode 100644
index 000000000000..4949b771ae74
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.sk.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ O programe
+
+
+ Vytvor novú veľkosť
+
+
+ Vymaž
+
+
+ Enkódovanie
+
+
+ Záložný encoder
+
+
+ Súbor
+
+
+ Meno súboru:
+
+
+ Pôvodné meno súboru
+
+
+ Názov veľkosti
+
+
+ Vybraná šírka
+
+
+ Vybraná výška
+
+
+ Skutočná šírka (pixely)
+
+
+ Skutočná výška (pixely)
+
+
+ Nasledujúce parametre sa môžu použiť
+
+
+ JPEG úroveň kvality
+
+
+ Použi pôvodný dátum úpravy
+
+
+ PNG interlacing
+
+
+ Veľkosti
+
+
+ TIFF kompresia:
+
+
+ Pokročilé Nastavenia
+
+
+ Všetky súbory
+
+
+ Zrušiť
+
+
+ © 2019 Brice Lambson. Všetky práva vyhradené.
+
+
+ Image Resizer for Windows
+
+
+ (auto)
+
+
+ Vyber veľkosť
+
+
+ Vlastné
+
+
+ Ignoruj otočenie obrázkov
+
+
+ Zmeň veľkosť obrázkov
+
+
+ Zmeň veľkosť originálov (nevytvoria sa kópie)
+
+
+ Zmeň Veľkosť
+
+
+ Pokročílé nastavenia...
+
+
+ Zmenši obrázky, nikdy nezväčšuj
+
+
+ Veľké
+
+
+ Stredné
+
+
+ OK
+
+
+ Telefón
+
+
+ Všetky obrázky
+
+
+ (Štandardné)
+
+
+ Vypnuté
+
+
+ Zapnuté
+
+
+ Zmeň veľkosť obrázkov...
+
+
+ _Stop
+
+
+ Ostáva približne {0} hod, {1} min
+
+
+ Ostáva približne {0} hod, {1} min
+
+
+ Ostáva približne {0} hod, {1} min
+
+
+ Ostáva približne {0} hod, {1} min
+
+
+ Ostáva približne {1} min, {2} sec
+
+
+ Ostáva približne {1} min, {2} sec
+
+
+ Ostáva približne {1} min, {2} sec
+
+
+ Ostáva približne {1} min, {2} sec
+
+
+ Ostáva približne {2} sec
+
+
+ Ostáva približne {2} sec
+
+
+ Vyplň
+
+
+ Vyplňuje
+
+
+ Prispôsob
+
+
+ Prispôsob do
+
+
+ Roztiahnuť
+
+
+ Roztiahnuť na
+
+
+ Centimetrov
+
+
+ Palcov
+
+
+ Percent
+
+
+ Pixely
+
+
+ Zatvor
+
+
+ Nemôžem spracovať nasledujúce obrázky
+
+
+ Malé
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Štandardné)
+
+
+ LZW
+
+
+ Žiadne
+
+
+ RLE
+
+
+ Zip
+
+
+ Hodnota musí byť medzi '{0}' a '{1}'.
+
+
+ Verzia
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.tr.resx b/ImageResizer/src/ImageResizer/Properties/Resources.tr.resx
new file mode 100644
index 000000000000..4c7fb878c865
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.tr.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Hakkında
+
+
+ Yeni bir boyut oluştur
+
+
+ Sil
+
+
+ Kodlama
+
+
+ Temel kodlayıcı:
+
+
+ Dosya
+
+
+ Dosya adı:
+
+
+ Orijinal dosya adı
+
+
+ Boyut adı
+
+
+ Seçili genişlik
+
+
+ Seçili yükseklik
+
+
+ Gerçek genişlik (piksel)
+
+
+ Gerçek yükseklik (piksel)
+
+
+ Aşağıdaki parametreler kullanılabilir.
+
+
+ JPEG kalite düzeyi:
+
+
+ Orijinal değiştirme tarihini kullan
+
+
+ PNG titreşimi:
+
+
+ Boyutlar
+
+
+ TIFF sıkıştırması:
+
+
+ Gelişmiş Seçenekler
+
+
+ Tüm Dosyalar
+
+
+ İptal
+
+
+ © 2019 Brice Lambson. Tüm hakları saklıdır.
+
+
+ Windows için Image Resizer
+
+
+ (otomatik)
+
+
+ Bir boyut seçin.
+
+
+ Özel
+
+
+ Resimlerin yönünü dikkate alma
+
+
+ Resimlerinizi yeniden boyutlandırın
+
+
+ Orijinal resimleri yeniden boyutlandır (kopya oluşturmaz)
+
+
+ Boyutlandır
+
+
+ Gelişmiş seçenekler...
+
+
+ Resimleri sadece küçültün, büyütmeyin
+
+
+ Büyük
+
+
+ Orta
+
+
+ Tamam
+
+
+ Telefon
+
+
+ Tüm Resim Dosyaları
+
+
+ (Varsayılan)
+
+
+ Kapalı
+
+
+ Açık
+
+
+ Resimleriniz yeniden boyutlandırılıyor...
+
+
+ Durdur
+
+
+ Yaklaşık {0} saat, {1} dakika kaldı.
+
+
+ Yaklaşık {0} saat, {1} dakika kaldı.
+
+
+ Yaklaşık {0} saat, {1} dakika kaldı.
+
+
+ Yaklaşık {0} saat, {1} dakika kaldı.
+
+
+ Yaklaşık {1} dakika, {2} saniye kaldı.
+
+
+ Yaklaşık {1} dakika, {2} saniye kaldı.
+
+
+ Yaklaşık {1} dakika, {2} saniye kaldı.
+
+
+ Yaklaşık {1} dakika, {2} saniye kaldı.
+
+
+ Yaklaşık {2} saniye kaldı.
+
+
+ Yaklaşık {2} saniye kaldı.
+
+
+ Doldur
+
+
+ doldurulacak değer
+
+
+ Sığdır
+
+
+ sığdırılacak değer
+
+
+ Uzat
+
+
+ uzatılacak değer
+
+
+ Santimetre
+
+
+ İnç
+
+
+ Yüzde
+
+
+ Piksel
+
+
+ Kapat
+
+
+ Aşağıdaki resimler yeniden boyutlandırılamıyor
+
+
+ Küçük
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (Varsayılan)
+
+
+ LZW
+
+
+ Yok
+
+
+ RLE
+
+
+ Zip
+
+
+ Değer '{0}' ile '{1}' arasında olmalıdır.
+
+
+ Sürüm
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Resources.zh-Hans.resx b/ImageResizer/src/ImageResizer/Properties/Resources.zh-Hans.resx
new file mode 100644
index 000000000000..45dd573fcdbb
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Resources.zh-Hans.resx
@@ -0,0 +1,345 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 关于
+
+
+ 新增尺寸
+
+
+ 删除
+
+
+ 编码中
+
+
+ 退回编码器:
+
+
+ 文件
+
+
+ 文件名
+
+
+ 原文件名
+
+
+ 尺寸名
+
+
+ 选定的宽度
+
+
+ 选定的高度
+
+
+ 实际宽度(像素)
+
+
+ 实际高度(像素)
+
+
+ 以下参数可供使用。
+
+
+ JPEG 图片质量等级:
+
+
+ 使用原来的文件修改日期
+
+
+ PNG 格式隔行扫描
+
+
+ 尺寸
+
+
+ TIFF 压缩
+
+
+ 高级选项
+
+
+ 所有文件
+
+
+ 取消
+
+
+ © 2019 Brice Lambson. 保留所有权利。
+
+
+ 重设图片大小(Windows 系统)
+
+
+ (自动)
+
+
+ 选择尺寸
+
+
+ 定制
+
+
+ 忽略图片方向
+
+
+ 重设图片大小
+
+
+ 缩放原图(不要创建备份)
+
+
+ 重设大小
+
+
+ 高级选项
+
+
+ 把图片缩小而不是放大
+
+
+ 大尺寸
+
+
+ 中尺寸
+
+
+ 确定
+
+
+ 手机
+
+
+ 所有图片文件
+
+
+ (默认)
+
+
+ 关闭
+
+
+ 打开
+
+
+ 正在重设图片大小……
+
+
+ 停止
+
+
+ 大约剩余 {0} 小时,{1} 分钟。
+
+
+ 大约剩余 {0} 小时,{1} 分钟。
+
+
+ 大约剩余 {0} 小时,{1} 分钟。
+
+
+ 大约剩余 {0} 小时,{1} 分钟。
+
+
+ 大约剩余 {0} 分钟,{1} 秒。
+
+
+ 大约剩余 {0} 分钟,{1} 秒。
+
+
+ 大约剩余 {0} 分钟,{1} 秒。
+
+
+ 大约剩余 {0} 分钟,{1} 秒。
+
+
+ 大约剩余 {0} 秒。
+
+
+ 大约剩余 {0} 秒。
+
+
+ 填充到
+
+
+ 填充
+
+
+ 适配到
+
+
+ 适配于
+
+
+ 拉伸
+
+
+ 拉伸到
+
+
+ 厘米
+
+
+ 英尺
+
+
+ 百分比
+
+
+ 像素
+
+
+ 关闭
+
+
+ 无法重设以下图片大小:
+
+
+ 小尺寸
+
+
+ CCITT3
+
+
+ CCITT4
+
+
+ (默认)
+
+
+ LZW
+
+
+ 无
+
+
+ RLE
+
+
+ Zip
+
+
+ 数值必须介于 '{0}' 和 '{1}' 之间.
+
+
+ 版本
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Properties/Settings.Designer.cs b/ImageResizer/src/ImageResizer/Properties/Settings.Designer.cs
new file mode 100644
index 000000000000..231dcf01c880
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Settings.Designer.cs
@@ -0,0 +1,221 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ImageResizer.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
+ public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("0")]
+ public int SelectedSizeIndex {
+ get {
+ return ((int)(this["SelectedSizeIndex"]));
+ }
+ set {
+ this["SelectedSizeIndex"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool ShrinkOnly {
+ get {
+ return ((bool)(this["ShrinkOnly"]));
+ }
+ set {
+ this["ShrinkOnly"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool Replace {
+ get {
+ return ((bool)(this["Replace"]));
+ }
+ set {
+ this["Replace"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool IgnoreOrientation {
+ get {
+ return ((bool)(this["IgnoreOrientation"]));
+ }
+ set {
+ this["IgnoreOrientation"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("90")]
+ public int JpegQualityLevel {
+ get {
+ return ((int)(this["JpegQualityLevel"]));
+ }
+ set {
+ this["JpegQualityLevel"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("Default")]
+ public global::System.Windows.Media.Imaging.PngInterlaceOption PngInterlaceOption {
+ get {
+ return ((global::System.Windows.Media.Imaging.PngInterlaceOption)(this["PngInterlaceOption"]));
+ }
+ set {
+ this["PngInterlaceOption"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("Default")]
+ public global::System.Windows.Media.Imaging.TiffCompressOption TiffCompressOption {
+ get {
+ return ((global::System.Windows.Media.Imaging.TiffCompressOption)(this["TiffCompressOption"]));
+ }
+ set {
+ this["TiffCompressOption"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("%1 (%2)")]
+ public string FileName {
+ get {
+ return ((string)(this["FileName"]));
+ }
+ set {
+ this["FileName"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute(@"
+
+
+ $small$
+ Fit
+ 854
+ 480
+ Pixel
+
+
+ $medium$
+ Fit
+ 1366
+ 768
+ Pixel
+
+
+ $large$
+ Fit
+ 1920
+ 1080
+ Pixel
+
+
+ $phone$
+ Fit
+ 320
+ 569
+ Pixel
+
+
+ ")]
+ public global::System.Collections.ObjectModel.ObservableCollection Sizes {
+ get {
+ return ((global::System.Collections.ObjectModel.ObservableCollection)(this["Sizes"]));
+ }
+ set {
+ this["Sizes"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool KeepDateModified {
+ get {
+ return ((bool)(this["KeepDateModified"]));
+ }
+ set {
+ this["KeepDateModified"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("19e4a5aa-5662-4fc5-a0c0-1758028e1057")]
+ public global::System.Guid FallbackEncoder {
+ get {
+ return ((global::System.Guid)(this["FallbackEncoder"]));
+ }
+ set {
+ this["FallbackEncoder"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute(@"
+
+ Custom
+ Fit
+ 1024
+ 640
+ Pixel
+
+ ")]
+ public global::ImageResizer.Models.CustomSize CustomSize {
+ get {
+ return ((global::ImageResizer.Models.CustomSize)(this["CustomSize"]));
+ }
+ set {
+ this["CustomSize"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool UpgradeRequired {
+ get {
+ return ((bool)(this["UpgradeRequired"]));
+ }
+ set {
+ this["UpgradeRequired"] = value;
+ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Properties/Settings.cs b/ImageResizer/src/ImageResizer/Properties/Settings.cs
new file mode 100644
index 000000000000..49019a4b6bad
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Settings.cs
@@ -0,0 +1,172 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using ImageResizer.Models;
+
+namespace ImageResizer.Properties
+{
+ partial class Settings : IDataErrorInfo
+ {
+ string _fileNameFormat;
+
+ public Settings()
+ => AllSizes = new AllSizesCollection(this);
+
+ public IEnumerable AllSizes { get; }
+
+ public string FileNameFormat
+ => _fileNameFormat
+ ?? (_fileNameFormat = FileName
+ .Replace("{", "{{")
+ .Replace("}", "}}")
+ .Replace("%1", "{0}")
+ .Replace("%2", "{1}")
+ .Replace("%3", "{2}")
+ .Replace("%4", "{3}")
+ .Replace("%5", "{4}")
+ .Replace("%6", "{5}"));
+
+ public ResizeSize SelectedSize
+ {
+ get => SelectedSizeIndex >= 0 && SelectedSizeIndex < Sizes.Count
+ ? Sizes[SelectedSizeIndex]
+ : CustomSize;
+ set
+ {
+ var index = Sizes.IndexOf(value);
+ if (index == -1)
+ index = Sizes.Count;
+
+ SelectedSizeIndex = index;
+ }
+ }
+
+ string IDataErrorInfo.Error
+ => string.Empty;
+
+ public override object this[string propertyName]
+ {
+ get { return base[propertyName]; }
+ set
+ {
+ base[propertyName] = value;
+
+ if (propertyName == nameof(FileName))
+ _fileNameFormat = null;
+ }
+ }
+
+ string IDataErrorInfo.this[string columnName]
+ {
+ get
+ {
+ if (columnName != nameof(JpegQualityLevel))
+ return string.Empty;
+
+ if (JpegQualityLevel < 1 || JpegQualityLevel > 100)
+ return string.Format(Resources.ValueMustBeBetween, 1, 100);
+
+ return string.Empty;
+ }
+ }
+
+ class AllSizesCollection : IEnumerable, INotifyCollectionChanged, INotifyPropertyChanged
+ {
+ ObservableCollection _sizes;
+ CustomSize _customSize;
+
+ public AllSizesCollection(Settings settings)
+ {
+ _sizes = settings.Sizes;
+ _customSize = settings.CustomSize;
+
+ _sizes.CollectionChanged += HandleCollectionChanged;
+ ((INotifyPropertyChanged)_sizes).PropertyChanged += HandlePropertyChanged;
+
+ settings.PropertyChanged += (sender, e) =>
+ {
+ if (e.PropertyName == nameof(CustomSize))
+ {
+ var oldCustomSize = _customSize;
+ _customSize = settings.CustomSize;
+
+ OnCollectionChanged(
+ new NotifyCollectionChangedEventArgs(
+ NotifyCollectionChangedAction.Replace,
+ _customSize,
+ oldCustomSize,
+ _sizes.Count));
+ }
+ else if (e.PropertyName == nameof(Sizes))
+ {
+ var oldSizes = _sizes;
+
+ oldSizes.CollectionChanged -= HandleCollectionChanged;
+ ((INotifyPropertyChanged)oldSizes).PropertyChanged -= HandlePropertyChanged;
+
+ _sizes = settings.Sizes;
+
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+
+ _sizes.CollectionChanged += HandleCollectionChanged;
+ ((INotifyPropertyChanged)_sizes).PropertyChanged += HandlePropertyChanged;
+ }
+ };
+ }
+
+ public event NotifyCollectionChangedEventHandler CollectionChanged;
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ public int Count
+ => _sizes.Count + 1;
+
+ public ResizeSize this[int index]
+ => index == _sizes.Count
+ ? _customSize
+ : _sizes[index];
+
+ public IEnumerator GetEnumerator()
+ => new AllSizesEnumerator(this);
+
+ void HandleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
+ => OnCollectionChanged(e);
+
+ void HandlePropertyChanged(object sender, PropertyChangedEventArgs e)
+ => PropertyChanged?.Invoke(this, e);
+
+ void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+ => CollectionChanged?.Invoke(this, e);
+
+ IEnumerator IEnumerable.GetEnumerator()
+ => GetEnumerator();
+
+ class AllSizesEnumerator : IEnumerator
+ {
+ readonly AllSizesCollection _list;
+
+ int _index = -1;
+
+ public AllSizesEnumerator(AllSizesCollection list)
+ => _list = list;
+
+ public ResizeSize Current
+ => _list[_index];
+
+ object IEnumerator.Current
+ => Current;
+
+ public void Dispose()
+ {
+ }
+
+ public bool MoveNext()
+ => ++_index < _list.Count;
+
+ public void Reset()
+ => _index = -1;
+ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Properties/Settings.settings b/ImageResizer/src/ImageResizer/Properties/Settings.settings
new file mode 100644
index 000000000000..1182f56af63d
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Properties/Settings.settings
@@ -0,0 +1,84 @@
+
+
+
+
+
+ 0
+
+
+ False
+
+
+ False
+
+
+ True
+
+
+ 90
+
+
+ Default
+
+
+ Default
+
+
+ %1 (%2)
+
+
+
+ <ArrayOfResizeSize xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <ResizeSize>
+ <Name>$small$</Name>
+ <Fit>Fit</Fit>
+ <Width>854</Width>
+ <Height>480</Height>
+ <Unit>Pixel</Unit>
+ </ResizeSize>
+ <ResizeSize>
+ <Name>$medium$</Name>
+ <Fit>Fit</Fit>
+ <Width>1366</Width>
+ <Height>768</Height>
+ <Unit>Pixel</Unit>
+ </ResizeSize>
+ <ResizeSize>
+ <Name>$large$</Name>
+ <Fit>Fit</Fit>
+ <Width>1920</Width>
+ <Height>1080</Height>
+ <Unit>Pixel</Unit>
+ </ResizeSize>
+ <ResizeSize>
+ <Name>$phone$</Name>
+ <Fit>Fit</Fit>
+ <Width>320</Width>
+ <Height>569</Height>
+ <Unit>Pixel</Unit>
+ </ResizeSize>
+ </ArrayOfResizeSize>
+
+
+
+ False
+
+
+ 19e4a5aa-5662-4fc5-a0c0-1758028e1057
+
+
+
+ <CustomSize xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Custom</Name>
+ <Fit>Fit</Fit>
+ <Width>1024</Width>
+ <Height>640</Height>
+ <Unit>Pixel</Unit>
+ </CustomSize>
+
+
+
+ True
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/Resources/ImageResizer.ico b/ImageResizer/src/ImageResizer/Resources/ImageResizer.ico
new file mode 100644
index 000000000000..accd1ee6b460
Binary files /dev/null and b/ImageResizer/src/ImageResizer/Resources/ImageResizer.ico differ
diff --git a/ImageResizer/src/ImageResizer/Resources/ImageResizer.png b/ImageResizer/src/ImageResizer/Resources/ImageResizer.png
new file mode 100644
index 000000000000..f196da96a8f9
Binary files /dev/null and b/ImageResizer/src/ImageResizer/Resources/ImageResizer.png differ
diff --git a/ImageResizer/src/ImageResizer/Utilities/MathHelpers.cs b/ImageResizer/src/ImageResizer/Utilities/MathHelpers.cs
new file mode 100644
index 000000000000..b51b6f4a418d
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Utilities/MathHelpers.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace ImageResizer.Utilities
+{
+ static class MathHelpers
+ {
+ public static int Clamp(int value, int min, int max)
+ => Math.Min(Math.Max(value, min), max);
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ViewModels/AdvancedViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/AdvancedViewModel.cs
new file mode 100644
index 000000000000..6b5726160923
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/AdvancedViewModel.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Windows.Input;
+using System.Windows.Media.Imaging;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using ImageResizer.Models;
+using ImageResizer.Properties;
+
+namespace ImageResizer.ViewModels
+{
+ public class AdvancedViewModel : ViewModelBase
+ {
+ static readonly IDictionary _encoderMap;
+
+ static AdvancedViewModel()
+ {
+ var bmpCodec = new BmpBitmapEncoder().CodecInfo;
+ var gifCodec = new GifBitmapEncoder().CodecInfo;
+ var jpegCodec = new JpegBitmapEncoder().CodecInfo;
+ var pngCodec = new PngBitmapEncoder().CodecInfo;
+ var tiffCodec = new TiffBitmapEncoder().CodecInfo;
+ var wmpCodec = new WmpBitmapEncoder().CodecInfo;
+
+ _encoderMap = new Dictionary
+ {
+ [bmpCodec.ContainerFormat] = bmpCodec.FriendlyName,
+ [gifCodec.ContainerFormat] = gifCodec.FriendlyName,
+ [jpegCodec.ContainerFormat] = jpegCodec.FriendlyName,
+ [pngCodec.ContainerFormat] = pngCodec.FriendlyName,
+ [tiffCodec.ContainerFormat] = tiffCodec.FriendlyName,
+ [wmpCodec.ContainerFormat] = wmpCodec.FriendlyName,
+ };
+ }
+
+ public AdvancedViewModel(Settings settings)
+ {
+ RemoveSizeCommand = new RelayCommand(RemoveSize);
+ AddSizeCommand = new RelayCommand(AddSize);
+ Settings = settings;
+ }
+
+ public static IDictionary EncoderMap
+ => _encoderMap;
+
+ public Settings Settings { get; }
+
+ public string Version
+ => typeof(AdvancedViewModel).Assembly.GetCustomAttribute()
+ ?.InformationalVersion;
+
+ public IEnumerable Encoders
+ => _encoderMap.Keys;
+
+ public ICommand RemoveSizeCommand { get; }
+ public ICommand AddSizeCommand { get; }
+
+ public void RemoveSize(ResizeSize size)
+ => Settings.Sizes.Remove(size);
+
+ public void AddSize()
+ => Settings.Sizes.Add(new ResizeSize());
+
+ public void Close(bool accepted)
+ {
+ if (accepted)
+ {
+ Settings.Save();
+
+ return;
+ }
+
+ var selectedSizeIndex = Settings.SelectedSizeIndex;
+ var shrinkOnly = Settings.ShrinkOnly;
+ var replace = Settings.Replace;
+ var ignoreOrientation = Settings.IgnoreOrientation;
+
+ Settings.Reload();
+ Settings.SelectedSizeIndex = selectedSizeIndex;
+ Settings.ShrinkOnly = shrinkOnly;
+ Settings.Replace = replace;
+ Settings.IgnoreOrientation = ignoreOrientation;
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ViewModels/ITabViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/ITabViewModel.cs
new file mode 100644
index 000000000000..5dd2ec956064
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/ITabViewModel.cs
@@ -0,0 +1,7 @@
+namespace ImageResizer.ViewModels
+{
+ public interface ITabViewModel
+ {
+ string Header { get; }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ViewModels/InputViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/InputViewModel.cs
new file mode 100644
index 000000000000..c1905f8cdf98
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/InputViewModel.cs
@@ -0,0 +1,52 @@
+using System.Windows.Input;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using ImageResizer.Models;
+using ImageResizer.Properties;
+using ImageResizer.Views;
+
+namespace ImageResizer.ViewModels
+{
+ public class InputViewModel : ViewModelBase
+ {
+ readonly ResizeBatch _batch;
+ readonly MainViewModel _mainViewModel;
+ readonly IMainView _mainView;
+
+ public InputViewModel(
+ Settings settings,
+ MainViewModel mainViewModel,
+ IMainView mainView,
+ ResizeBatch batch)
+ {
+ _batch = batch;
+ _mainViewModel = mainViewModel;
+ _mainView = mainView;
+
+ Settings = settings;
+ settings.CustomSize.PropertyChanged += (sender, e) => settings.SelectedSize = (CustomSize)sender;
+
+ ResizeCommand = new RelayCommand(Resize);
+ CancelCommand = new RelayCommand(Cancel);
+ ShowAdvancedCommand = new RelayCommand(ShowAdvanced);
+ }
+
+ public Settings Settings { get; }
+
+ public ICommand ResizeCommand { get; }
+ public ICommand CancelCommand { get; }
+ public ICommand ShowAdvancedCommand { get; }
+
+ public void Resize()
+ {
+ Settings.Save();
+ _mainViewModel.CurrentPage = new ProgressViewModel(_batch, _mainViewModel, _mainView);
+ }
+
+ public void Cancel()
+ => _mainView.Close();
+
+ public void ShowAdvanced()
+ => _mainView.ShowAdvanced(new AdvancedViewModel(Settings));
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ViewModels/MainViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/MainViewModel.cs
new file mode 100644
index 000000000000..b2680aa3b9c0
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/MainViewModel.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using System.Windows.Input;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using ImageResizer.Models;
+using ImageResizer.Properties;
+using ImageResizer.Views;
+
+namespace ImageResizer.ViewModels
+{
+ public class MainViewModel : ViewModelBase
+ {
+ readonly Settings _settings;
+ readonly ResizeBatch _batch;
+
+ object _currentPage;
+ double _progress;
+
+ public MainViewModel(ResizeBatch batch, Settings settings)
+ {
+ _batch = batch;
+ _settings = settings;
+ LoadCommand = new RelayCommand(Load);
+ }
+
+ public ICommand LoadCommand { get; }
+
+ public object CurrentPage
+ {
+ get => _currentPage;
+ set => Set(nameof(CurrentPage), ref _currentPage, value);
+ }
+
+ public double Progress
+ {
+ get => _progress;
+ set => Set(nameof(Progress), ref _progress, value);
+ }
+
+ public void Load(IMainView view)
+ {
+ if (_batch.Files.Count == 0)
+ _batch.Files.AddRange(view.OpenPictureFiles());
+
+ if (_settings.UpgradeRequired)
+ {
+ _settings.Upgrade();
+ _settings.UpgradeRequired = false;
+ _settings.Save();
+ }
+
+ CurrentPage = new InputViewModel(_settings, this, view, _batch);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ImageResizer/src/ImageResizer/ViewModels/ProgressViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/ProgressViewModel.cs
new file mode 100644
index 000000000000..8f34b0a8c4ac
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/ProgressViewModel.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using ImageResizer.Models;
+using ImageResizer.Views;
+
+namespace ImageResizer.ViewModels
+{
+ public class ProgressViewModel : ViewModelBase
+ {
+ readonly MainViewModel _mainViewModel;
+ readonly ResizeBatch _batch;
+ readonly IMainView _mainView;
+ readonly Stopwatch _stopwatch = new Stopwatch();
+ readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
+
+ double _progress;
+ TimeSpan _timeRemaining;
+
+ public ProgressViewModel(
+ ResizeBatch batch,
+ MainViewModel mainViewModel,
+ IMainView mainView)
+ {
+ _batch = batch;
+ _mainViewModel = mainViewModel;
+ _mainView = mainView;
+
+ StartCommand = new RelayCommand(Start);
+ StopCommand = new RelayCommand(Stop);
+ }
+
+ public double Progress
+ {
+ get => _progress;
+ set => Set(nameof(Progress), ref _progress, value);
+ }
+
+ public TimeSpan TimeRemaining
+ {
+ get => _timeRemaining;
+ set => Set(nameof(TimeRemaining), ref _timeRemaining, value);
+ }
+
+ public ICommand StartCommand { get; }
+ public ICommand StopCommand { get; }
+
+ public void Start()
+ => Task.Factory.StartNew(
+ () =>
+ {
+ _stopwatch.Restart();
+ var errors = _batch.Process(
+ _cancellationTokenSource.Token,
+ (completed, total) =>
+ {
+ var progress = completed / total;
+ Progress = progress;
+ _mainViewModel.Progress = progress;
+
+ TimeRemaining = _stopwatch.Elapsed.Multiply((total - completed) / completed);
+ });
+
+ if (errors.Any())
+ {
+ _mainViewModel.Progress = 0;
+ _mainViewModel.CurrentPage = new ResultsViewModel(_mainView, errors);
+ }
+ else
+ {
+ _mainView.Close();
+ }
+ },
+ _cancellationTokenSource.Token);
+
+ public void Stop()
+ {
+ _cancellationTokenSource.Cancel();
+ _mainView.Close();
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/ViewModels/ResultsViewModel.cs b/ImageResizer/src/ImageResizer/ViewModels/ResultsViewModel.cs
new file mode 100644
index 000000000000..eb6ff1f6dd97
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/ViewModels/ResultsViewModel.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using System.Windows.Input;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using ImageResizer.Models;
+using ImageResizer.Views;
+
+namespace ImageResizer.ViewModels
+{
+ public class ResultsViewModel : ViewModelBase
+ {
+ readonly IMainView _mainView;
+
+ public ResultsViewModel(IMainView mainView, IEnumerable errors)
+ {
+ _mainView = mainView;
+ Errors = errors;
+ CloseCommand = new RelayCommand(Close);
+ }
+
+ public IEnumerable Errors { get; }
+ public ICommand CloseCommand { get; }
+
+ public void Close() => _mainView.Close();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml b/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml
new file mode 100644
index 000000000000..5234ddf22929
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml
@@ -0,0 +1,295 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %2 -
+
+
+ %3 -
+
+
+ %4 -
+
+
+ %5 -
+
+
+ %6 -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://bricelam.net/ImageResizer
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml.cs b/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml.cs
new file mode 100644
index 000000000000..3ff70fa43dbb
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/AdvancedWindow.xaml.cs
@@ -0,0 +1,25 @@
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Navigation;
+using ImageResizer.ViewModels;
+
+namespace ImageResizer.Views
+{
+ public partial class AdvancedWindow : Window
+ {
+ public AdvancedWindow(AdvancedViewModel viewModel)
+ {
+ DataContext = viewModel;
+ InitializeComponent();
+ }
+
+ void HandleAcceptClick(object sender, RoutedEventArgs e)
+ => DialogResult = true;
+
+ void HandleRequestNavigate(object sender, RequestNavigateEventArgs e)
+ {
+ Process.Start(e.Uri.ToString());
+ e.Handled = true;
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/AutoDoubleConverter.cs b/ImageResizer/src/ImageResizer/Views/AutoDoubleConverter.cs
new file mode 100644
index 000000000000..8437c1fa7f64
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/AutoDoubleConverter.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(double), typeof(string))]
+ class AutoDoubleConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var d = (double)value;
+
+ return d != 0
+ ? d.ToString(culture)
+ : (string)parameter == "Auto"
+ ? Resources.Input_Auto
+ : string.Empty;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var text = (string)value;
+
+ return !string.IsNullOrEmpty(text)
+ ? double.Parse(text, culture)
+ : 0;
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/AutoDoubleValidationRule.cs b/ImageResizer/src/ImageResizer/Views/AutoDoubleValidationRule.cs
new file mode 100644
index 000000000000..90882f818625
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/AutoDoubleValidationRule.cs
@@ -0,0 +1,18 @@
+using System.Globalization;
+using System.Windows.Controls;
+
+namespace ImageResizer.Views
+{
+ class AutoDoubleValidationRule : ValidationRule
+ {
+ public override ValidationResult Validate(object value, CultureInfo cultureInfo)
+ {
+ var text = (string)value;
+
+ return new ValidationResult(
+ string.IsNullOrEmpty(text)
+ || double.TryParse(text, NumberStyles.AllowThousands | NumberStyles.Float, cultureInfo, out var _),
+ null);
+ }
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/BoolValueConverter.cs b/ImageResizer/src/ImageResizer/Views/BoolValueConverter.cs
new file mode 100644
index 000000000000..41c9cf8ba83f
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/BoolValueConverter.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(Enum), typeof(string))]
+ class BoolValueConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ => (bool)value ? Visibility.Visible : Visibility.Collapsed;
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => throw new NotImplementedException();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/ContainerFormatConverter.cs b/ImageResizer/src/ImageResizer/Views/ContainerFormatConverter.cs
new file mode 100644
index 000000000000..553f90b070a4
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ContainerFormatConverter.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using ImageResizer.ViewModels;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(Guid), typeof(string))]
+ public class ContainerFormatConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ => AdvancedViewModel.EncoderMap.TryGetValue((Guid)value, out var result)
+ ? result
+ : value.ToString();
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => throw new NotImplementedException();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/EnumValueConverter.cs b/ImageResizer/src/ImageResizer/Views/EnumValueConverter.cs
new file mode 100644
index 000000000000..7fc358880591
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/EnumValueConverter.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Globalization;
+using System.Text;
+using System.Windows.Data;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(Enum), typeof(string))]
+ public class EnumValueConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var type = value.GetType();
+ var builder = new StringBuilder();
+
+ builder
+ .Append(type.Name)
+ .Append("_")
+ .Append(Enum.GetName(type, value));
+
+ var toLower = false;
+ if ((string)parameter == "ToLower")
+ {
+ toLower = true;
+ }
+ else if (parameter != null)
+ {
+ builder
+ .Append("_")
+ .Append(parameter);
+ }
+
+ var targetValue = Resources.ResourceManager.GetString(builder.ToString());
+
+ if (toLower)
+ targetValue = targetValue.ToLower();
+
+ return targetValue;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => value;
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/IMainView.cs b/ImageResizer/src/ImageResizer/Views/IMainView.cs
new file mode 100644
index 000000000000..dbfde9fd47be
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/IMainView.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using ImageResizer.ViewModels;
+
+namespace ImageResizer.Views
+{
+ public interface IMainView
+ {
+ void Close();
+ void ShowAdvanced(AdvancedViewModel viewModel);
+ IEnumerable OpenPictureFiles();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/InputPage.xaml b/ImageResizer/src/ImageResizer/Views/InputPage.xaml
new file mode 100644
index 000000000000..ca8918ea7396
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/InputPage.xaml
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/Views/InputPage.xaml.cs b/ImageResizer/src/ImageResizer/Views/InputPage.xaml.cs
new file mode 100644
index 000000000000..12f4c2ffae28
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/InputPage.xaml.cs
@@ -0,0 +1,10 @@
+using System.Windows.Controls;
+
+namespace ImageResizer.Views
+{
+ public partial class InputPage : UserControl
+ {
+ public InputPage()
+ => InitializeComponent();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/MainWindow.xaml b/ImageResizer/src/ImageResizer/Views/MainWindow.xaml
new file mode 100644
index 000000000000..354c043d0bbe
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/MainWindow.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/Views/MainWindow.xaml.cs b/ImageResizer/src/ImageResizer/Views/MainWindow.xaml.cs
new file mode 100644
index 000000000000..70e4af7d8a8c
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/MainWindow.xaml.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows;
+using ImageResizer.ViewModels;
+using Microsoft.Win32;
+using AppResources = ImageResizer.Properties.Resources;
+
+namespace ImageResizer.Views
+{
+ public partial class MainWindow : Window, IMainView
+ {
+ public MainWindow(MainViewModel viewModel)
+ {
+ DataContext = viewModel;
+ InitializeComponent();
+ }
+
+ public IEnumerable OpenPictureFiles()
+ {
+ var openFileDialog = new OpenFileDialog
+ {
+ Filter = AppResources.PictureFilter +
+ "|*.bmp;*.dib;*.exif;*.gif;*.jfif;*.jpe;*.jpeg;*.jpg;*.jxr;*.png;*.rle;*.tif;*.tiff;*.wdp|" +
+ AppResources.AllFilesFilter + "|*.*",
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
+ Multiselect = true
+ };
+
+ if (openFileDialog.ShowDialog() != true)
+ return Enumerable.Empty();
+
+ return openFileDialog.FileNames;
+ }
+
+ public void ShowAdvanced(AdvancedViewModel viewModel)
+ => viewModel.Close(new AdvancedWindow(viewModel).ShowDialog() == true);
+
+ void IMainView.Close()
+ => Dispatcher.Invoke((Action)Close);
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml b/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml
new file mode 100644
index 000000000000..72735f2c798c
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml.cs b/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml.cs
new file mode 100644
index 000000000000..ecd8860fc013
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ProgressPage.xaml.cs
@@ -0,0 +1,10 @@
+using System.Windows.Controls;
+
+namespace ImageResizer.Views
+{
+ public partial class ProgressPage : UserControl
+ {
+ public ProgressPage()
+ => InitializeComponent();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/ResizeUnitConverter.cs b/ImageResizer/src/ImageResizer/Views/ResizeUnitConverter.cs
new file mode 100644
index 000000000000..1766beabc718
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ResizeUnitConverter.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using ImageResizer.Models;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(ResizeUnit), typeof(string))]
+ class ResizeUnitConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var output = Resources.ResourceManager.GetString(Enum.GetName(typeof(ResizeUnit), value));
+
+ if ((string)parameter == "ToLower")
+ {
+ output = output.ToLower(culture);
+ }
+
+ return output;
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => throw new NotImplementedException();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml b/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml
new file mode 100644
index 000000000000..32260be30c7a
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml.cs b/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml.cs
new file mode 100644
index 000000000000..0d23a718e913
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/ResultsPage.xaml.cs
@@ -0,0 +1,10 @@
+using System.Windows.Controls;
+
+namespace ImageResizer.Views
+{
+ public partial class ResultsPage : UserControl
+ {
+ public ResultsPage()
+ => InitializeComponent();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/TiffCompressOptionConverter.cs b/ImageResizer/src/ImageResizer/Views/TiffCompressOptionConverter.cs
new file mode 100644
index 000000000000..772598763d40
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/TiffCompressOptionConverter.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Globalization;
+using System.Windows.Data;
+using System.Windows.Media.Imaging;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(TiffCompressOption), typeof(string))]
+ class TiffCompressOptionConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ => Resources.ResourceManager.GetString(
+ "TiffCompressOption_" + Enum.GetName(typeof(TiffCompressOption), value));
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => throw new NotImplementedException();
+ }
+}
diff --git a/ImageResizer/src/ImageResizer/Views/TimeRemainingConverter.cs b/ImageResizer/src/ImageResizer/Views/TimeRemainingConverter.cs
new file mode 100644
index 000000000000..3ce05bfd3920
--- /dev/null
+++ b/ImageResizer/src/ImageResizer/Views/TimeRemainingConverter.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Globalization;
+using System.Text;
+using System.Windows.Data;
+using ImageResizer.Properties;
+
+namespace ImageResizer.Views
+{
+ [ValueConversion(typeof(TimeSpan), typeof(string))]
+ class TimeRemainingConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var timeRemaining = (TimeSpan)value;
+
+ var builder = new StringBuilder("Progress_TimeRemaining_");
+
+ if (timeRemaining.Hours != 0)
+ {
+ builder.Append(timeRemaining.Hours == 1 ? "Hour" : "Hours");
+ }
+ if (timeRemaining.Hours != 0 || timeRemaining.Minutes > 0)
+ {
+ builder.Append(timeRemaining.Minutes == 1 ? "Minute" : "Minutes");
+ }
+ if (timeRemaining.Hours == 0)
+ {
+ builder.Append(timeRemaining.Seconds == 1 ? "Second" : "Seconds");
+ }
+
+ return string.Format(
+ culture,
+ Resources.ResourceManager.GetString(builder.ToString()),
+ timeRemaining.Hours,
+ timeRemaining.Minutes,
+ timeRemaining.Seconds);
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ => throw new NotImplementedException();
+ }
+}
diff --git a/ImageResizer/src/ShellExtensions/ContextMenuHandler.cpp b/ImageResizer/src/ShellExtensions/ContextMenuHandler.cpp
new file mode 100644
index 000000000000..cc88bd3a4462
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ContextMenuHandler.cpp
@@ -0,0 +1,223 @@
+// ContextMenuHandler.cpp : Implementation of CContextMenuHandler
+
+#include "stdafx.h"
+#include "ContextMenuHandler.h"
+#include "HDropIterator.h"
+
+CContextMenuHandler::CContextMenuHandler()
+{
+ m_pidlFolder = NULL;
+ m_pdtobj = NULL;
+}
+
+CContextMenuHandler::~CContextMenuHandler()
+{
+ Uninitialize();
+}
+
+void CContextMenuHandler::Uninitialize()
+{
+ CoTaskMemFree((LPVOID)m_pidlFolder);
+ m_pidlFolder = NULL;
+
+ if (m_pdtobj)
+ {
+ m_pdtobj->Release();
+ m_pdtobj = NULL;
+ }
+}
+
+HRESULT CContextMenuHandler::Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _In_opt_ IDataObject *pdtobj, _In_opt_ HKEY hkeyProgID)
+{
+ Uninitialize();
+
+ if (pidlFolder)
+ {
+ m_pidlFolder = ILClone(pidlFolder);
+ }
+
+ if (pdtobj)
+ {
+ m_pdtobj = pdtobj;
+ m_pdtobj->AddRef();
+ }
+
+ return S_OK;
+}
+
+HRESULT CContextMenuHandler::QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
+{
+ if (uFlags & CMF_DEFAULTONLY)
+ {
+ return S_OK;
+ }
+
+ // NB: We just check the first item. We could iterate through more if the first one doesn't meet the criteria
+ HDropIterator i(m_pdtobj);
+ i.First();
+
+ PERCEIVED type;
+ PERCEIVEDFLAG flag;
+ LPTSTR pszPath = i.CurrentItem();
+ LPTSTR pszExt = PathFindExtension(pszPath);
+
+ // TODO: Instead, detech whether there's a WIC codec installd that can handle this file (issue #7)
+ AssocGetPerceivedType(pszExt, &type, &flag, NULL);
+
+ free(pszPath);
+
+ // If selected file is an image...
+ if (type == PERCEIVED_TYPE_IMAGE)
+ {
+ CString strResizePictures;
+
+ // If handling drag-and-drop...
+ if (m_pidlFolder)
+ {
+ // Load 'Resize pictures here' string
+ strResizePictures.LoadString(IDS_RESIZE_PICTURES_HERE);
+ }
+ else
+ {
+ // Load 'Resize pictures' string
+ strResizePictures.LoadString(IDS_RESIZE_PICTURES);
+ }
+
+ // Add menu item
+ InsertMenu(hmenu, indexMenu, MF_BYPOSITION, idCmdFirst + ID_RESIZE_PICTURES, strResizePictures);
+
+ return MAKE_HRESULT(SEVERITY_SUCCESS, 0, ID_RESIZE_PICTURES + 1);
+ }
+
+ return S_OK;
+}
+
+HRESULT CContextMenuHandler::GetCommandString(UINT_PTR idCmd, UINT uType, _In_ UINT *pReserved, LPSTR pszName, UINT cchMax)
+{
+ if (idCmd == ID_RESIZE_PICTURES)
+ {
+ if (uType == GCS_VERBW)
+ {
+ wcscpy_s((LPWSTR)pszName, cchMax, RESIZE_PICTURES_VERBW);
+ }
+ }
+ else
+ {
+ return E_INVALIDARG;
+ }
+
+ return S_OK;
+}
+
+HRESULT CContextMenuHandler::InvokeCommand(_In_ CMINVOKECOMMANDINFO *pici)
+{
+ BOOL fUnicode = FALSE;
+
+ if (pici->cbSize == sizeof(CMINVOKECOMMANDINFOEX)
+ && pici->fMask & CMIC_MASK_UNICODE)
+ {
+ fUnicode = TRUE;
+ }
+
+ if (!fUnicode && HIWORD(pici->lpVerb))
+ {
+ }
+ else if (fUnicode && HIWORD(((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW))
+ {
+ if (wcscmp(((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW, RESIZE_PICTURES_VERBW) == 0)
+ {
+ return ResizePictures(pici);
+ }
+ }
+ else if (LOWORD(pici->lpVerb) == ID_RESIZE_PICTURES)
+ {
+ return ResizePictures(pici);
+ }
+
+ return E_FAIL;
+}
+
+// TODO: Error handling and memory management
+HRESULT CContextMenuHandler::ResizePictures(CMINVOKECOMMANDINFO *pici)
+{
+ // Set the application path from the registry
+ LPTSTR lpApplicationName = new TCHAR[MAX_PATH];
+ ULONG nChars = MAX_PATH;
+ CRegKey regKey;
+
+ // NB: The location is always read from a 32-bit key
+ if (regKey.Open(HKEY_CURRENT_USER, _T("Software\\BriceLambson\\ImageResizer"), KEY_READ | KEY_WOW64_32KEY))
+ {
+ regKey.Open(HKEY_LOCAL_MACHINE, _T("Software\\BriceLambson\\ImageResizer"), KEY_READ | KEY_WOW64_32KEY);
+ }
+
+ regKey.QueryStringValue(NULL, lpApplicationName, &nChars);
+ regKey.Close();
+
+ // Create an anonymous pipe to stream filenames
+ SECURITY_ATTRIBUTES sa;
+ HANDLE hReadPipe;
+ HANDLE hWritePipe;
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+ CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
+ SetHandleInformation(hWritePipe, HANDLE_FLAG_INHERIT, 0);
+ CAtlFile writePipe(hWritePipe);
+
+ CString commandLine;
+ commandLine.Format(_T("\"%s\""), lpApplicationName);
+ delete[] lpApplicationName;
+
+ // Set the output directory
+ if (m_pidlFolder)
+ {
+ TCHAR szFolder[MAX_PATH];
+ SHGetPathFromIDList(m_pidlFolder, szFolder);
+
+ commandLine.AppendFormat(_T(" /d \"%s\""), szFolder);
+ }
+
+ int nSize = commandLine.GetLength() + 1;
+ LPTSTR lpszCommandLine = new TCHAR[nSize];
+ _tcscpy_s(lpszCommandLine, nSize, commandLine);
+
+ STARTUPINFO startupInfo;
+ ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
+ startupInfo.cb = sizeof(STARTUPINFO);
+ startupInfo.hStdInput = hReadPipe;
+ startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
+ startupInfo.wShowWindow = pici->nShow;
+
+ PROCESS_INFORMATION processInformation;
+
+ // Start the resizer
+ CreateProcess(
+ NULL,
+ lpszCommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ NULL,
+ NULL,
+ &startupInfo,
+ &processInformation);
+ delete[] lpszCommandLine;
+ CloseHandle(processInformation.hProcess);
+ CloseHandle(processInformation.hThread);
+
+ // Stream the input files
+ HDropIterator i(m_pdtobj);
+ for (i.First(); !i.IsDone(); i.Next())
+ {
+ CString fileName(i.CurrentItem());
+ fileName.Append(_T("\r\n"));
+
+ writePipe.Write(fileName, fileName.GetLength() * sizeof(TCHAR));
+ }
+
+ writePipe.Close();
+
+ return S_OK;
+}
diff --git a/ImageResizer/src/ShellExtensions/ContextMenuHandler.h b/ImageResizer/src/ShellExtensions/ContextMenuHandler.h
new file mode 100644
index 000000000000..677a7e990ee8
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ContextMenuHandler.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#define ID_RESIZE_PICTURES 0
+#define RESIZE_PICTURES_VERBW L"resize"
+
+#include "resource.h"
+#include "ShellExtensions_i.h"
+
+#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
+#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
+#endif
+
+using namespace ATL;
+
+class ATL_NO_VTABLE CContextMenuHandler :
+ public CComObjectRootEx,
+ public CComCoClass,
+ public IShellExtInit,
+ public IContextMenu
+{
+ BEGIN_COM_MAP(CContextMenuHandler)
+ COM_INTERFACE_ENTRY(IShellExtInit)
+ COM_INTERFACE_ENTRY(IContextMenu)
+ END_COM_MAP()
+ DECLARE_REGISTRY_RESOURCEID(IDR_CONTEXTMENUHANDLER)
+ DECLARE_NOT_AGGREGATABLE(CContextMenuHandler)
+
+public:
+ CContextMenuHandler();
+ ~CContextMenuHandler();
+ HRESULT STDMETHODCALLTYPE Initialize(_In_opt_ PCIDLIST_ABSOLUTE pidlFolder, _In_opt_ IDataObject *pdtobj, _In_opt_ HKEY hkeyProgID);
+ HRESULT STDMETHODCALLTYPE QueryContextMenu(_In_ HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
+ HRESULT STDMETHODCALLTYPE GetCommandString(UINT_PTR idCmd, UINT uType, _In_ UINT *pReserved, LPSTR pszName, UINT cchMax);
+ HRESULT STDMETHODCALLTYPE InvokeCommand(_In_ CMINVOKECOMMANDINFO *pici);
+
+private:
+ void Uninitialize();
+ HRESULT ResizePictures(CMINVOKECOMMANDINFO *pici);
+ PCIDLIST_ABSOLUTE m_pidlFolder;
+ IDataObject *m_pdtobj;
+};
+
+OBJECT_ENTRY_AUTO(__uuidof(ContextMenuHandler), CContextMenuHandler)
diff --git a/ImageResizer/src/ShellExtensions/ContextMenuHandler.rgs b/ImageResizer/src/ShellExtensions/ContextMenuHandler.rgs
new file mode 100644
index 000000000000..8aac22c301d1
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ContextMenuHandler.rgs
@@ -0,0 +1,35 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {51B4D7E5-7568-4234-B4BB-47FB3C016A69} = s 'ContextMenuHandler Class'
+ {
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ TypeLib = s '{09082E28-A5CA-47A7-8571-A2236C411E91}'
+ Version = s '3.1'
+ }
+ }
+ NoRemove Directory
+ {
+ NoRemove ShellEx
+ {
+ NoRemove DragDropHandlers
+ {
+ ForceRemove 'Image Resizer' = s '{51B4D7E5-7568-4234-B4BB-47FB3C016A69}'
+ }
+ }
+ }
+ NoRemove *
+ {
+ NoRemove ShellEx
+ {
+ NoRemove ContextMenuHandlers
+ {
+ ForceRemove 'Image Resizer' = s '{51B4D7E5-7568-4234-B4BB-47FB3C016A69}'
+ }
+ }
+ }
+}
diff --git a/ImageResizer/src/ShellExtensions/HDropIterator.cpp b/ImageResizer/src/ShellExtensions/HDropIterator.cpp
new file mode 100644
index 000000000000..b2d25111d3b0
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/HDropIterator.cpp
@@ -0,0 +1,50 @@
+#include "StdAfx.h"
+#include "HDropIterator.h"
+
+HDropIterator::HDropIterator(IDataObject *pdtobj)
+{
+ _current = 0;
+
+ FORMATETC formatetc =
+ {
+ CF_HDROP,
+ NULL,
+ DVASPECT_CONTENT,
+ -1,
+ TYMED_HGLOBAL
+ };
+
+ pdtobj->GetData(&formatetc, &m_medium);
+
+ _listCount = DragQueryFile((HDROP)m_medium.hGlobal, 0xFFFFFFFF, NULL, 0);
+}
+
+HDropIterator::~HDropIterator()
+{
+ ReleaseStgMedium(&m_medium);
+}
+
+void HDropIterator::First()
+{
+ _current = 0;
+}
+
+void HDropIterator::Next()
+{
+ _current++;
+}
+
+bool HDropIterator::IsDone() const
+{
+ return _current >= _listCount;
+}
+
+LPTSTR HDropIterator::CurrentItem() const
+{
+ UINT cch = DragQueryFile((HDROP)m_medium.hGlobal, _current, NULL, 0) + 1;
+ LPTSTR pszPath = (LPTSTR)malloc(sizeof(TCHAR) * cch);
+
+ DragQueryFile((HDROP)m_medium.hGlobal, _current, pszPath, cch);
+
+ return pszPath;
+}
diff --git a/ImageResizer/src/ShellExtensions/HDropIterator.h b/ImageResizer/src/ShellExtensions/HDropIterator.h
new file mode 100644
index 000000000000..8f1d26151d86
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/HDropIterator.h
@@ -0,0 +1,17 @@
+#pragma once
+
+class HDropIterator
+{
+public:
+ HDropIterator(IDataObject *pDataObject);
+ ~HDropIterator();
+ void First();
+ void Next();
+ bool IsDone() const;
+ LPTSTR CurrentItem() const;
+
+private:
+ UINT _listCount;
+ STGMEDIUM m_medium;
+ UINT _current;
+};
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.cpp b/ImageResizer/src/ShellExtensions/ShellExtensions.cpp
new file mode 100644
index 000000000000..e77b725f8e0e
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.cpp
@@ -0,0 +1,54 @@
+#include "stdafx.h"
+#include "resource.h"
+#include "ShellExtensions_i.h"
+#include "dllmain.h"
+
+STDAPI DllCanUnloadNow()
+{
+ return _AtlModule.DllCanUnloadNow();
+}
+
+STDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)
+{
+ return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
+}
+
+STDAPI DllRegisterServer()
+{
+ return _AtlModule.DllRegisterServer();
+}
+
+STDAPI DllUnregisterServer()
+{
+ return _AtlModule.DllUnregisterServer();
+}
+
+STDAPI DllInstall(BOOL bInstall, _In_opt_ LPCWSTR pszCmdLine)
+{
+ HRESULT hr = E_FAIL;
+ static const wchar_t szUserSwitch[] = L"user";
+
+ if (pszCmdLine != NULL)
+ {
+ if (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)
+ {
+ ATL::AtlSetPerUserRegistration(true);
+ }
+ }
+
+ if (bInstall)
+ {
+ hr = DllRegisterServer();
+
+ if (FAILED(hr))
+ {
+ DllUnregisterServer();
+ }
+ }
+ else
+ {
+ hr = DllUnregisterServer();
+ }
+
+ return hr;
+}
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.def b/ImageResizer/src/ShellExtensions/ShellExtensions.def
new file mode 100644
index 000000000000..cd58c84c283d
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.def
@@ -0,0 +1,8 @@
+LIBRARY
+
+EXPORTS
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE
+ DllInstall PRIVATE
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.idl b/ImageResizer/src/ShellExtensions/ShellExtensions.idl
new file mode 100644
index 000000000000..26acca8b1788
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.idl
@@ -0,0 +1,15 @@
+import "shobjidl.idl";
+
+[
+ uuid(09082E28-A5CA-47A7-8571-A2236C411E91),
+ version(3.1)
+]
+library ShellExtensionsLib
+{
+ [uuid(51B4D7E5-7568-4234-B4BB-47FB3C016A69)]
+ coclass ContextMenuHandler
+ {
+ [default] interface IShellExtInit;
+ interface IContextMenu;
+ };
+};
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.rc b/ImageResizer/src/ShellExtensions/ShellExtensions.rc
new file mode 100644
index 000000000000..a91895f81f35
Binary files /dev/null and b/ImageResizer/src/ShellExtensions/ShellExtensions.rc differ
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.rgs b/ImageResizer/src/ShellExtensions/ShellExtensions.rgs
new file mode 100644
index 000000000000..e7d37400e19a
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.rgs
@@ -0,0 +1,3 @@
+HKCR
+{
+}
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj b/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj
new file mode 100644
index 000000000000..548f691606c7
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj
@@ -0,0 +1,287 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {0B43679E-EDFA-4DA0-AD30-F4628B308B1B}
+ 10.0
+ AtlProj
+
+
+
+ DynamicLibrary
+ true
+ Static
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ Static
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ true
+ Static
+ v142
+ Unicode
+
+
+ DynamicLibrary
+ false
+ Static
+ v142
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+ true
+ true
+
+
+ true
+ false
+
+
+ true
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ false
+ Win32
+ _DEBUG;%(PreprocessorDefinitions)
+ ShellExtensions_i.h
+ ShellExtensions_i.c
+ ShellExtensions_p.c
+ true
+ $(IntDir)ShellExtensions.tlb
+
+ true
+
+
+ 0x0409
+ $(IntDir);%(AdditionalIncludeDirectories)
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\ShellExtensions.def
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ Disabled
+ _WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+ ShellExtensions_i.h
+ ShellExtensions_i.c
+ ShellExtensions_p.c
+ true
+ $(IntDir)ShellExtensions.tlb
+
+ true
+
+
+ 0x0409
+ $(IntDir);%(AdditionalIncludeDirectories)
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\ShellExtensions.def
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ false
+ Win32
+ NDEBUG;%(PreprocessorDefinitions)
+ ShellExtensions_i.h
+ ShellExtensions_i.c
+ ShellExtensions_p.c
+ true
+ $(IntDir)ShellExtensions.tlb
+
+ true
+
+
+ 0x0409
+ $(IntDir);%(AdditionalIncludeDirectories)
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\ShellExtensions.def
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+ Use
+ Level3
+ MaxSpeed
+ _WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+ ShellExtensions_i.h
+ ShellExtensions_i.c
+ ShellExtensions_p.c
+ true
+ $(IntDir)ShellExtensions.tlb
+
+ true
+
+
+ 0x0409
+ $(IntDir);%(AdditionalIncludeDirectories)
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ .\ShellExtensions.def
+ true
+ true
+ true
+ true
+ true
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj.filters b/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj.filters
new file mode 100644
index 000000000000..f6ced56a9d6f
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/ShellExtensions.vcxproj.filters
@@ -0,0 +1,85 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {87bc9b81-f7fa-45d9-87cc-c99e55473868}
+ False
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Generated Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Generated Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+ Source Files
+
+
+ Resource Files
+
+
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/src/ShellExtensions/dllmain.cpp b/ImageResizer/src/ShellExtensions/dllmain.cpp
new file mode 100644
index 000000000000..b8d69d978e0b
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/dllmain.cpp
@@ -0,0 +1,11 @@
+#include "stdafx.h"
+#include "resource.h"
+#include "ShellExtensions_i.h"
+#include "dllmain.h"
+
+CShellExtensionsModule _AtlModule;
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
+{
+ return _AtlModule.DllMain(dwReason, lpReserved);
+}
diff --git a/ImageResizer/src/ShellExtensions/dllmain.h b/ImageResizer/src/ShellExtensions/dllmain.h
new file mode 100644
index 000000000000..0e8f22a4aa22
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/dllmain.h
@@ -0,0 +1,8 @@
+class CShellExtensionsModule : public ATL::CAtlDllModuleT< CShellExtensionsModule >
+{
+public:
+ DECLARE_LIBID(LIBID_ShellExtensionsLib)
+ DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SHELLEXTENSIONS, "{0C866E7B-65CB-4E7D-B1DD-D014F000E8D8}")
+};
+
+extern class CShellExtensionsModule _AtlModule;
diff --git a/ImageResizer/src/ShellExtensions/resource.h b/ImageResizer/src/ShellExtensions/resource.h
new file mode 100644
index 000000000000..838c13a57e08
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/resource.h
@@ -0,0 +1,19 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ShellExtensions.rc
+//
+#define IDS_RESIZE_PICTURES 100
+#define IDS_RESIZE_PICTURES_HERE 101
+#define IDR_SHELLEXTENSIONS 101
+#define IDR_CONTEXTMENUHANDLER 102
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 201
+#define _APS_NEXT_COMMAND_VALUE 32768
+#define _APS_NEXT_CONTROL_VALUE 201
+#define _APS_NEXT_SYMED_VALUE 103
+#endif
+#endif
diff --git a/ImageResizer/src/ShellExtensions/stdafx.cpp b/ImageResizer/src/ShellExtensions/stdafx.cpp
new file mode 100644
index 000000000000..fd4f341c7b24
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/stdafx.cpp
@@ -0,0 +1 @@
+#include "stdafx.h"
diff --git a/ImageResizer/src/ShellExtensions/stdafx.h b/ImageResizer/src/ShellExtensions/stdafx.h
new file mode 100644
index 000000000000..fc538545f7bd
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/stdafx.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#ifndef STRICT
+#define STRICT
+#endif
+
+#define _ATL_APARTMENT_THREADED
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+#define ATL_NO_ASSERT_ON_DESTROY_NONEXISTENT_WINDOW
+
+#include "targetver.h"
+#include "resource.h"
+
+#include
+#include
+#include
+#include
+
+#include
diff --git a/ImageResizer/src/ShellExtensions/targetver.h b/ImageResizer/src/ShellExtensions/targetver.h
new file mode 100644
index 000000000000..895f499ce391
--- /dev/null
+++ b/ImageResizer/src/ShellExtensions/targetver.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#define _WIN32_WINNT _WIN32_WINNT_WINXP
+#define _WIN32_IE _WIN32_IE_XPSP2
+
+#include
+#include
diff --git a/ImageResizer/test/ImageResizer.Test/App.config b/ImageResizer/test/ImageResizer.Test/App.config
new file mode 100644
index 000000000000..088ab21a4930
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/ImageResizer/test/ImageResizer.Test/ImageResizer.Test.csproj b/ImageResizer/test/ImageResizer.Test/ImageResizer.Test.csproj
new file mode 100644
index 000000000000..686a16df6bd4
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/ImageResizer.Test.csproj
@@ -0,0 +1,92 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {E0CC7526-D85E-43AC-844F-D5DF0D2F5AB8}
+ Library
+ Properties
+ ImageResizer
+ ImageResizer.Test
+ v4.0
+ 512
+ Client
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+ {2be46397-4dfa-414c-9bd4-41e4bbf8cb34}
+ ImageResizer
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+ 4.2.1510.2205
+
+
+ 4.4.0
+
+
+ 1.9.2
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ImageResizer/test/ImageResizer.Test/Models/CustomSizeTests.cs b/ImageResizer/test/ImageResizer.Test/Models/CustomSizeTests.cs
new file mode 100644
index 000000000000..337d2c4978c0
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Models/CustomSizeTests.cs
@@ -0,0 +1,18 @@
+using ImageResizer.Properties;
+using Xunit;
+
+namespace ImageResizer.Models
+{
+ public class CustomSizeTests
+ {
+ [Fact]
+ public void Name_works()
+ {
+ var size = new CustomSize();
+
+ size.Name = "Ignored";
+
+ Assert.Equal(Resources.Input_Custom, size.Name);
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Models/ResizeBatchTests.cs b/ImageResizer/test/ImageResizer.Test/Models/ResizeBatchTests.cs
new file mode 100644
index 000000000000..712384be1d6a
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Models/ResizeBatchTests.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Moq;
+using Moq.Protected;
+using Xunit;
+
+namespace ImageResizer.Models
+{
+ public class ResizeBatchTests
+ {
+ static readonly string EOL = Environment.NewLine;
+
+ [Fact]
+ public void FromCommandLine_works()
+ {
+ var standardInput =
+ "Image1.jpg" + EOL +
+ "Image2.jpg";
+ var args = new[]
+ {
+ "/d", "OutputDir",
+ "Image3.jpg"
+ };
+
+ var result = ResizeBatch.FromCommandLine(
+ new StringReader(standardInput),
+ args);
+
+ Assert.Equal(new List { "Image1.jpg", "Image2.jpg", "Image3.jpg" }, result.Files);
+
+ Assert.Equal("OutputDir", result.DestinationDirectory);
+ }
+
+ [Fact]
+ public void Process_executes_in_parallel()
+ {
+ var batch = CreateBatch(_ => Thread.Sleep(50));
+ batch.Files.AddRange(
+ Enumerable.Range(0, Environment.ProcessorCount)
+ .Select(i => "Image" + i + ".jpg"));
+
+ var stopwatch = Stopwatch.StartNew();
+ batch.Process(CancellationToken.None, (_, __) => { });
+ stopwatch.Stop();
+
+ Assert.InRange(stopwatch.ElapsedMilliseconds, 50, 99);
+ }
+
+ [Fact]
+ public void Process_aggregates_errors()
+ {
+ var batch = CreateBatch(file => throw new Exception("Error: " + file));
+ batch.Files.Add("Image1.jpg");
+ batch.Files.Add("Image2.jpg");
+
+ var errors = batch.Process(CancellationToken.None, (_, __) => { }).ToList();
+
+ Assert.Equal(2, errors.Count);
+
+ var errorFiles = new List();
+
+ foreach (var error in errors)
+ {
+ errorFiles.Add(error.File);
+ Assert.Equal("Error: " + error.File, error.Error);
+ }
+
+ foreach (var file in batch.Files)
+ {
+ Assert.Contains(file, errorFiles);
+ }
+ }
+
+ [Fact]
+ public void Process_reports_progress()
+ {
+ var batch = CreateBatch(_ => { });
+ batch.Files.Add("Image1.jpg");
+ batch.Files.Add("Image2.jpg");
+ var calls = new ConcurrentBag<(int i, double count)>();
+
+ batch.Process(
+ CancellationToken.None,
+ (i, count) => calls.Add((i, count)));
+
+ Assert.Equal(2, calls.Count);
+ Assert.True(calls.Any(c => c.i == 1 && c.count == 2));
+ Assert.True(calls.Any(c => c.i == 2 && c.count == 2));
+ }
+
+ static ResizeBatch CreateBatch(Action executeAction)
+ {
+ var mock = new Mock { CallBase = true };
+ mock.Protected().Setup("Execute", ItExpr.IsAny()).Callback(executeAction);
+
+ return mock.Object;
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Models/ResizeOperationTests.cs b/ImageResizer/test/ImageResizer.Test/Models/ResizeOperationTests.cs
new file mode 100644
index 000000000000..fbeddd44b666
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Models/ResizeOperationTests.cs
@@ -0,0 +1,449 @@
+using System;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using ImageResizer.Properties;
+using ImageResizer.Test;
+using Xunit;
+
+namespace ImageResizer.Models
+{
+ public class ResizeOperationTests : IDisposable
+ {
+ readonly TestDirectory _directory = new TestDirectory();
+
+ [Fact]
+ public void Execute_copies_frame_metadata()
+ {
+ var operation = new ResizeOperation("Test.jpg", _directory, Settings());
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image => Assert.Equal("Test", ((BitmapMetadata)image.Frames[0].Metadata).Comment));
+ }
+
+ [Fact]
+ public void Execute_keeps_date_modified()
+ {
+ var operation = new ResizeOperation("Test.png", _directory, Settings(s => s.KeepDateModified = true));
+
+ operation.Execute();
+
+ Assert.Equal(File.GetLastWriteTimeUtc("Test.png"), File.GetLastWriteTimeUtc(_directory.File()));
+ }
+
+ [Fact]
+ public void Execute_keeps_date_modified_when_replacing_originals()
+ {
+ var path = Path.Combine(_directory, "Test.png");
+ File.Copy("Test.png", path);
+
+ var originalDateModified = File.GetLastWriteTimeUtc(path);
+
+ var operation = new ResizeOperation(
+ path,
+ null,
+ Settings(
+ s =>
+ {
+ s.KeepDateModified = true;
+ s.Replace = true;
+ }));
+
+ operation.Execute();
+
+ Assert.Equal(originalDateModified, File.GetLastWriteTimeUtc(_directory.File()));
+ }
+
+ [Fact]
+ public void Execute_replaces_originals()
+ {
+ var path = Path.Combine(_directory, "Test.png");
+ File.Copy("Test.png", path);
+
+ var operation = new ResizeOperation(path, null, Settings(s => s.Replace = true));
+
+ operation.Execute();
+
+ AssertEx.Image(_directory.File(), image => Assert.Equal(96, image.Frames[0].PixelWidth));
+ }
+
+ [Fact]
+ public void Execute_transforms_each_frame()
+ {
+ var operation = new ResizeOperation("Test.gif", _directory, Settings());
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(2, image.Frames.Count);
+ AssertEx.All(image.Frames, frame => Assert.Equal(96, frame.PixelWidth));
+ });
+ }
+
+ [Fact]
+ public void Execute_uses_fallback_encoder()
+ {
+ var operation = new ResizeOperation(
+ "Test.ico",
+ _directory,
+ Settings(s => s.FallbackEncoder = new PngBitmapEncoder().CodecInfo.ContainerFormat));
+
+ operation.Execute();
+
+ Assert.Contains("Test (Test).png", _directory.FileNames);
+ }
+
+ [Fact]
+ public void Transform_ignores_orientation_when_landscape_to_portrait()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.IgnoreOrientation = true;
+ x.SelectedSize.Width = 96;
+ x.SelectedSize.Height = 192;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(192, image.Frames[0].PixelWidth);
+ Assert.Equal(96, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_ignores_orientation_when_portrait_to_landscape()
+ {
+ var operation = new ResizeOperation(
+ "TestPortrait.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.IgnoreOrientation = true;
+ x.SelectedSize.Width = 192;
+ x.SelectedSize.Height = 96;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(192, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_ignores_ignore_orientation_when_auto()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.IgnoreOrientation = true;
+ x.SelectedSize.Width = 96;
+ x.SelectedSize.Height = 0;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(48, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_ignores_ignore_orientation_when_percent()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.IgnoreOrientation = true;
+ x.SelectedSize.Width = 50;
+ x.SelectedSize.Height = 200;
+ x.SelectedSize.Unit = ResizeUnit.Percent;
+ x.SelectedSize.Fit = ResizeFit.Stretch;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(192, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_honors_shrink_only()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.ShrinkOnly = true;
+ x.SelectedSize.Width = 288;
+ x.SelectedSize.Height = 288;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(192, image.Frames[0].PixelWidth);
+ Assert.Equal(96, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_ignores_shrink_only_when_percent()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.ShrinkOnly = true;
+ x.SelectedSize.Width = 133.3;
+ x.SelectedSize.Unit = ResizeUnit.Percent;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(256, image.Frames[0].PixelWidth);
+ Assert.Equal(128, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_honors_shrink_only_when_auto_height()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.ShrinkOnly = true;
+ x.SelectedSize.Width = 288;
+ x.SelectedSize.Height = 0;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image => Assert.Equal(192, image.Frames[0].PixelWidth));
+ }
+
+ [Fact]
+ public void Transform_honors_shrink_only_when_auto_width()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.ShrinkOnly = true;
+ x.SelectedSize.Width = 0;
+ x.SelectedSize.Height = 288;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image => Assert.Equal(96, image.Frames[0].PixelHeight));
+ }
+
+ [Fact]
+ public void Transform_honors_unit()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(
+ x =>
+ {
+ x.SelectedSize.Width = 1;
+ x.SelectedSize.Height = 1;
+ x.SelectedSize.Unit = ResizeUnit.Inch;
+ }));
+
+ operation.Execute();
+
+ AssertEx.Image(_directory.File(), image => Assert.Equal(image.Frames[0].DpiX, image.Frames[0].PixelWidth, 0));
+ }
+
+ [Fact]
+ public void Transform_honors_fit_when_Fit()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(x => x.SelectedSize.Fit = ResizeFit.Fit));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(48, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_honors_fit_when_Fill()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(x => x.SelectedSize.Fit = ResizeFit.Fill));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(Colors.White, image.Frames[0].GetFirstPixel());
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(96, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void Transform_honors_fit_when_Stretch()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(x => x.SelectedSize.Fit = ResizeFit.Stretch));
+
+ operation.Execute();
+
+ AssertEx.Image(
+ _directory.File(),
+ image =>
+ {
+ Assert.Equal(Colors.Black, image.Frames[0].GetFirstPixel());
+ Assert.Equal(96, image.Frames[0].PixelWidth);
+ Assert.Equal(96, image.Frames[0].PixelHeight);
+ });
+ }
+
+ [Fact]
+ public void GetDestinationPath_uniquifies_output_filename()
+ {
+ File.WriteAllBytes(Path.Combine(_directory, "Test (Test).png"), new byte[0]);
+
+ var operation = new ResizeOperation("Test.png", _directory, Settings());
+
+ operation.Execute();
+
+ Assert.Contains("Test (Test) (1).png", _directory.FileNames);
+ }
+
+ [Fact]
+ public void GetDestinationPath_uniquifies_output_filename_again()
+ {
+ File.WriteAllBytes(Path.Combine(_directory, "Test (Test).png"), new byte[0]);
+ File.WriteAllBytes(Path.Combine(_directory, "Test (Test) (1).png"), new byte[0]);
+
+ var operation = new ResizeOperation("Test.png", _directory, Settings());
+
+ operation.Execute();
+
+ Assert.Contains("Test (Test) (2).png", _directory.FileNames);
+ }
+
+ [Fact]
+ public void GetDestinationPath_uses_fileName_format()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(s => s.FileName = "%1_%2_%3_%4_%5_%6"));
+
+ operation.Execute();
+
+ Assert.Contains("Test_Test_96_96_96_48.png", _directory.FileNames);
+ }
+
+ [Fact]
+ public void Execute_handles_directories_in_fileName_format()
+ {
+ var operation = new ResizeOperation(
+ "Test.png",
+ _directory,
+ Settings(s => s.FileName = @"Directory\%1 (%2)"));
+
+ operation.Execute();
+
+ Assert.True(File.Exists(_directory + @"\Directory\Test (Test).png"));
+ }
+
+ public void Dispose()
+ => _directory.Dispose();
+
+ Settings Settings(Action action = null)
+ {
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection
+ {
+ new ResizeSize
+ {
+ Name = "Test",
+ Width = 96,
+ Height = 96
+ }
+ },
+ SelectedSizeIndex = 0
+ };
+ action?.Invoke(settings);
+
+ return settings;
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Models/ResizeSizeTests.cs b/ImageResizer/test/ImageResizer.Test/Models/ResizeSizeTests.cs
new file mode 100644
index 000000000000..14ea84da049e
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Models/ResizeSizeTests.cs
@@ -0,0 +1,268 @@
+using System.Collections.Generic;
+using System.ComponentModel;
+using ImageResizer.Properties;
+using ImageResizer.Test;
+using Xunit;
+using Xunit.Extensions;
+
+namespace ImageResizer.Models
+{
+ public class ResizeSizeTests
+ {
+ [Fact]
+ public void Name_works()
+ {
+ var size = new ResizeSize();
+
+ var e = AssertEx.Raises(
+ h => size.PropertyChanged += h,
+ h => size.PropertyChanged -= h,
+ () => size.Name = "Test");
+
+ Assert.Equal("Test", size.Name);
+ Assert.Equal(nameof(ResizeSize.Name), e.Arguments.PropertyName);
+ }
+
+ [Fact]
+ public void Name_replaces_tokens()
+ {
+ var args = new List<(string, string)>
+ {
+ ("$small$", Resources.Small),
+ ("$medium$", Resources.Medium),
+ ("$large$", Resources.Large),
+ ("$phone$", Resources.Phone)
+ };
+ foreach (var (name, expected) in args)
+ {
+ var size = new ResizeSize();
+
+ size.Name = name;
+
+ Assert.Equal(expected, size.Name);
+ }
+ }
+
+ [Fact]
+ public void Fit_works()
+ {
+ var size = new ResizeSize();
+
+ var e = AssertEx.Raises(
+ h => size.PropertyChanged += h,
+ h => size.PropertyChanged -= h,
+ () => size.Fit = ResizeFit.Stretch);
+
+ Assert.Equal(ResizeFit.Stretch, size.Fit);
+ Assert.Equal(nameof(ResizeSize.Fit), e.Arguments.PropertyName);
+ }
+
+ [Fact]
+ public void Width_works()
+ {
+ var size = new ResizeSize();
+
+ var e = AssertEx.Raises(
+ h => size.PropertyChanged += h,
+ h => size.PropertyChanged -= h,
+ () => size.Width = 42);
+
+ Assert.Equal(42, size.Width);
+ Assert.Equal(nameof(ResizeSize.Width), e.Arguments.PropertyName);
+ }
+
+ [Fact]
+ public void Height_works()
+ {
+ var size = new ResizeSize();
+
+ var e = AssertEx.Raises(
+ h => size.PropertyChanged += h,
+ h => size.PropertyChanged -= h,
+ () => size.Height = 42);
+
+ Assert.Equal(42, size.Height);
+ Assert.Equal(nameof(ResizeSize.Height), e.Arguments.PropertyName);
+ }
+
+ [Fact]
+ public void HasAuto_returns_true_when_Width_unset()
+ {
+ var size = new ResizeSize
+ {
+ Width = 0,
+ Height = 42
+ };
+
+ Assert.True(size.HasAuto);
+ }
+
+ [Fact]
+ public void HasAuto_returns_true_when_Height_unset()
+ {
+ var size = new ResizeSize
+ {
+ Width = 42,
+ Height = 0
+ };
+
+ Assert.True(size.HasAuto);
+ }
+
+ [Fact]
+ public void HasAuto_returns_false_when_Width_and_Height_set()
+ {
+ var size = new ResizeSize
+ {
+ Width = 42,
+ Height = 42
+ };
+
+ Assert.False(size.HasAuto);
+ }
+
+ [Fact]
+ public void Unit_works()
+ {
+ var size = new ResizeSize();
+
+ var e = AssertEx.Raises(
+ h => size.PropertyChanged += h,
+ h => size.PropertyChanged -= h,
+ () => size.Unit = ResizeUnit.Inch);
+
+ Assert.Equal(ResizeUnit.Inch, size.Unit);
+ Assert.Equal(nameof(ResizeSize.Unit), e.Arguments.PropertyName);
+ }
+
+ [Fact]
+ public void GetPixelWidth_works()
+ {
+ var size = new ResizeSize
+ {
+ Width = 1,
+ Unit = ResizeUnit.Inch
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(96, result);
+ }
+
+ [Fact]
+ public void GetPixelHeight_works()
+ {
+ var size = new ResizeSize
+ {
+ Height = 1,
+ Unit = ResizeUnit.Inch
+ };
+
+ var result = size.GetPixelHeight(100, 96);
+
+ Assert.Equal(96, result);
+ }
+
+ [Theory]
+ [InlineData(ResizeFit.Fit)]
+ [InlineData(ResizeFit.Fill)]
+ public void GetPixelHeight_uses_Width_when_scale_by_percent(ResizeFit fit)
+ {
+ var size = new ResizeSize
+ {
+ Fit = fit,
+ Width = 100,
+ Height = 50,
+ Unit = ResizeUnit.Percent,
+ };
+
+ var result = size.GetPixelHeight(100, 96);
+
+ Assert.Equal(100, result);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_auto_and_fit()
+ {
+ var size = new ResizeSize
+ {
+ Width = 0,
+ Fit = ResizeFit.Fit
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(double.PositiveInfinity, result);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_auto_and_not_fit()
+ {
+ var size = new ResizeSize
+ {
+ Width = 0,
+ Fit = ResizeFit.Fill
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(100, result);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_inches()
+ {
+ var size = new ResizeSize
+ {
+ Width = 0.5,
+ Unit = ResizeUnit.Inch
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(48, result);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_centimeters()
+ {
+ var size = new ResizeSize
+ {
+ Width = 1,
+ Unit = ResizeUnit.Centimeter
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(38, result, 0);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_percent()
+ {
+ var size = new ResizeSize
+ {
+ Width = 50,
+ Unit = ResizeUnit.Percent
+ };
+
+ var result = size.GetPixelWidth(200, 96);
+
+ Assert.Equal(100, result);
+ }
+
+ [Fact]
+ public void ConvertToPixels_works_when_pixels()
+ {
+ var size = new ResizeSize
+ {
+ Width = 50,
+ Unit = ResizeUnit.Pixel
+ };
+
+ var result = size.GetPixelWidth(100, 96);
+
+ Assert.Equal(50, result);
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Properties/SettingsTests.cs b/ImageResizer/test/ImageResizer.Test/Properties/SettingsTests.cs
new file mode 100644
index 000000000000..23955bf8517d
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Properties/SettingsTests.cs
@@ -0,0 +1,186 @@
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using ImageResizer.Models;
+using ImageResizer.Test;
+using Xunit;
+using Xunit.Extensions;
+
+namespace ImageResizer.Properties
+{
+ public class SettingsTests
+ {
+ [Fact]
+ public void AllSizes_propagates_Sizes_collection_events()
+ {
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection(),
+ CustomSize = new CustomSize()
+ };
+ var ncc = (INotifyCollectionChanged)settings.AllSizes;
+
+ var result = AssertEx.Raises(
+ h => ncc.CollectionChanged += h,
+ h => ncc.CollectionChanged -= h,
+ () => settings.Sizes.Add(new ResizeSize()));
+
+ Assert.Equal(NotifyCollectionChangedAction.Add, result.Arguments.Action);
+ }
+
+ [Fact]
+ public void AllSizes_propagates_Sizes_property_events()
+ {
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection(),
+ CustomSize = new CustomSize()
+ };
+
+ Assert.PropertyChanged(
+ (INotifyPropertyChanged)settings.AllSizes,
+ "Item[]",
+ () => settings.Sizes.Add(new ResizeSize()));
+ }
+
+ [Fact]
+ public void AllSizes_contains_Sizes()
+ {
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection { new ResizeSize() },
+ CustomSize = new CustomSize()
+ };
+
+ Assert.Contains(settings.Sizes[0], settings.AllSizes);
+ }
+
+ [Fact]
+ public void AllSizes_contains_CustomSize()
+ {
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection(),
+ CustomSize = new CustomSize()
+ };
+
+ Assert.Contains(settings.CustomSize, settings.AllSizes);
+ }
+
+ [Fact]
+ public void AllSizes_handles_property_events_for_CustomSize()
+ {
+ var originalCustomSize = new CustomSize();
+ var settings = new Settings
+ {
+ Sizes = new ObservableCollection(),
+ CustomSize = originalCustomSize
+ };
+ var ncc = (INotifyCollectionChanged)settings.AllSizes;
+
+ var result = AssertEx.Raises(
+ h => ncc.CollectionChanged += h,
+ h => ncc.CollectionChanged -= h,
+ () => settings.CustomSize = new CustomSize());
+
+ Assert.Equal(NotifyCollectionChangedAction.Replace, result.Arguments.Action);
+ Assert.Equal(1, result.Arguments.NewItems.Count);
+ Assert.Equal(settings.CustomSize, result.Arguments.NewItems[0]);
+ Assert.Equal(0, result.Arguments.NewStartingIndex);
+ Assert.Equal(1, result.Arguments.OldItems.Count);
+ Assert.Equal(originalCustomSize, result.Arguments.OldItems[0]);
+ Assert.Equal(0, result.Arguments.OldStartingIndex);
+ }
+
+ [Fact]
+ public void FileNameFormat_works()
+ {
+ var settings = new Settings { FileName = "{T}%1e%2s%3t%4%5%6%7" };
+
+ var result = settings.FileNameFormat;
+
+ Assert.Equal("{{T}}{0}e{1}s{2}t{3}{4}{5}%7", result);
+ }
+
+ [Theory]
+ [InlineData(0)]
+ [InlineData(1)]
+ [InlineData(2)]
+ public void SelectedSize_returns_CustomSize_when_out_of_range(int index)
+ {
+ var settings = new Settings
+ {
+ SelectedSizeIndex = index,
+ Sizes = new ObservableCollection(),
+ CustomSize = new CustomSize()
+ };
+
+ var result = settings.SelectedSize;
+
+ Assert.Same(settings.CustomSize, result);
+ }
+
+ [Fact]
+ public void SelectedSize_returns_Size_when_in_range()
+ {
+ var settings = new Settings
+ {
+ SelectedSizeIndex = 0,
+ Sizes = new ObservableCollection
+ {
+ new ResizeSize()
+ }
+ };
+
+ var result = settings.SelectedSize;
+
+ Assert.Same(settings.Sizes[0], result);
+ }
+
+ [Fact]
+ public void IDataErrorInfo_Error_returns_empty()
+ {
+ var settings = new Settings();
+
+ var result = ((IDataErrorInfo)settings).Error;
+
+ Assert.Empty(result);
+ }
+
+ [Theory]
+ [InlineData(0)]
+ [InlineData(101)]
+ public void IDataErrorInfo_Item_JpegQualityLevel_returns_error_when_out_of_range(int value)
+ {
+ var settings = new Settings { JpegQualityLevel = value };
+
+ var result = ((IDataErrorInfo)settings)["JpegQualityLevel"];
+
+ Assert.Equal(
+ string.Format(Resources.ValueMustBeBetween, 1, 100),
+ result);
+ }
+
+ [Theory]
+ [InlineData(1)]
+ [InlineData(100)]
+ public void IDataErrorInfo_Item_JpegQualityLevel_returns_empty_when_in_range(int value)
+ {
+ var settings = new Settings { JpegQualityLevel = value };
+
+ var result = ((IDataErrorInfo)settings)["JpegQualityLevel"];
+
+ Assert.Empty(result);
+ }
+
+ [Fact]
+ public void IDataErrorInfo_Item_returns_empty_when_not_JpegQualityLevel()
+ {
+ var settings = new Settings();
+
+ var result = ((IDataErrorInfo)settings)["Unknown"];
+
+ Assert.Empty(result);
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Test.gif b/ImageResizer/test/ImageResizer.Test/Test.gif
new file mode 100644
index 000000000000..b09c588a6078
Binary files /dev/null and b/ImageResizer/test/ImageResizer.Test/Test.gif differ
diff --git a/ImageResizer/test/ImageResizer.Test/Test.ico b/ImageResizer/test/ImageResizer.Test/Test.ico
new file mode 100644
index 000000000000..c6bbbb621aa1
Binary files /dev/null and b/ImageResizer/test/ImageResizer.Test/Test.ico differ
diff --git a/ImageResizer/test/ImageResizer.Test/Test.jpg b/ImageResizer/test/ImageResizer.Test/Test.jpg
new file mode 100644
index 000000000000..70e13bf52865
Binary files /dev/null and b/ImageResizer/test/ImageResizer.Test/Test.jpg differ
diff --git a/ImageResizer/test/ImageResizer.Test/Test.png b/ImageResizer/test/ImageResizer.Test/Test.png
new file mode 100644
index 000000000000..e4f09732cf16
Binary files /dev/null and b/ImageResizer/test/ImageResizer.Test/Test.png differ
diff --git a/ImageResizer/test/ImageResizer.Test/Test/AssertEx.cs b/ImageResizer/test/ImageResizer.Test/Test/AssertEx.cs
new file mode 100644
index 000000000000..9e0f3a235f44
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Test/AssertEx.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.ComponentModel;
+using System.IO;
+using System.Windows.Media.Imaging;
+using Xunit;
+
+namespace ImageResizer.Test
+{
+ static class AssertEx
+ {
+ public static void All(IEnumerable collection, Action action)
+ {
+ foreach (var item in collection)
+ {
+ action(item);
+ }
+ }
+
+ public static void Image(string path, Action action)
+ {
+ using (var stream = File.OpenRead(path))
+ {
+ var image = BitmapDecoder.Create(
+ stream,
+ BitmapCreateOptions.PreservePixelFormat,
+ BitmapCacheOption.None);
+
+ action(image);
+ }
+ }
+
+ public static RaisedEvent Raises(
+ Action attach,
+ Action detach,
+ Action testCode)
+ where T : NotifyCollectionChangedEventArgs
+ {
+ RaisedEvent raisedEvent = null;
+ NotifyCollectionChangedEventHandler handler = (sender, e)
+ => raisedEvent = new RaisedEvent(sender, e);
+ attach(handler);
+ testCode();
+ detach(handler);
+
+ Assert.NotNull(raisedEvent);
+
+ return raisedEvent;
+ }
+
+ public static RaisedEvent Raises(
+ Action attach,
+ Action detach,
+ Action testCode)
+ where T : PropertyChangedEventArgs
+ {
+ RaisedEvent raisedEvent = null;
+ PropertyChangedEventHandler handler = (sender, e)
+ => raisedEvent = new RaisedEvent(sender, e);
+ attach(handler);
+ testCode();
+ detach(handler);
+
+ Assert.NotNull(raisedEvent);
+
+ return raisedEvent;
+ }
+
+ public class RaisedEvent
+ {
+ public RaisedEvent(object sender, TArgs args)
+ {
+ Sender = sender;
+ Arguments = args;
+ }
+
+ public object Sender { get; }
+ public TArgs Arguments { get; }
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Test/BitmapSourceExtensions.cs b/ImageResizer/test/ImageResizer.Test/Test/BitmapSourceExtensions.cs
new file mode 100644
index 000000000000..2386e3bc5a2c
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Test/BitmapSourceExtensions.cs
@@ -0,0 +1,22 @@
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace ImageResizer.Test
+{
+ static class BitmapSourceExtensions
+ {
+ public static Color GetFirstPixel(this BitmapSource source)
+ {
+ var pixel = new byte[4];
+ new FormatConvertedBitmap(
+ new CroppedBitmap(source, new Int32Rect(0, 0, 1, 1)),
+ PixelFormats.Bgra32,
+ destinationPalette: null,
+ alphaThreshold: 0)
+ .CopyPixels(pixel, 4, 0);
+
+ return Color.FromArgb(pixel[3], pixel[2], pixel[1], pixel[0]);
+ }
+ }
+}
diff --git a/ImageResizer/test/ImageResizer.Test/Test/TestDirectory.cs b/ImageResizer/test/ImageResizer.Test/Test/TestDirectory.cs
new file mode 100644
index 000000000000..37b310dd28fa
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Test/TestDirectory.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using Xunit;
+using IOPath = System.IO.Path;
+
+namespace ImageResizer
+{
+ public class TestDirectory : IDisposable
+ {
+ readonly string _path;
+
+ public TestDirectory()
+ {
+ _path = IOPath.Combine(
+ AppDomain.CurrentDomain.BaseDirectory,
+ IOPath.GetRandomFileName());
+ Directory.CreateDirectory(_path);
+ }
+
+ IEnumerable Files
+ => Directory.EnumerateFiles(_path);
+
+ public IEnumerable FileNames
+ => Files.Select(IOPath.GetFileName);
+
+ public string File()
+ => Assert.Single(Files);
+
+ public void Dispose()
+ {
+ var stopwatch = Stopwatch.StartNew();
+ while (stopwatch.ElapsedMilliseconds < 30000)
+ {
+ try
+ {
+ Directory.Delete(_path, recursive: true);
+ break;
+ }
+ catch
+ {
+ Thread.Sleep(150);
+ }
+ }
+ }
+
+ public static implicit operator string(TestDirectory directory)
+ => directory._path;
+ }
+}
\ No newline at end of file
diff --git a/ImageResizer/test/ImageResizer.Test/TestPortrait.png b/ImageResizer/test/ImageResizer.Test/TestPortrait.png
new file mode 100644
index 000000000000..dbc49c6741ee
Binary files /dev/null and b/ImageResizer/test/ImageResizer.Test/TestPortrait.png differ
diff --git a/ImageResizer/test/ImageResizer.Test/Views/TimeRemainingConverterTests.cs b/ImageResizer/test/ImageResizer.Test/Views/TimeRemainingConverterTests.cs
new file mode 100644
index 000000000000..e1112c4e0950
--- /dev/null
+++ b/ImageResizer/test/ImageResizer.Test/Views/TimeRemainingConverterTests.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Globalization;
+using ImageResizer.Properties;
+using Xunit;
+using Xunit.Extensions;
+
+namespace ImageResizer.Views
+{
+ public class TimeRemainingConverterTests
+ {
+ [Theory]
+ [InlineData("HourMinute", 1, 1, 0)]
+ [InlineData("HourMinutes", 1, 2, 0)]
+ [InlineData("HoursMinute", 2, 1, 0)]
+ [InlineData("HoursMinutes", 2, 2, 0)]
+ [InlineData("MinuteSecond", 0, 1, 1)]
+ [InlineData("MinuteSeconds", 0, 1, 2)]
+ [InlineData("MinutesSecond", 0, 2, 1)]
+ [InlineData("MinutesSeconds", 0, 2, 2)]
+ [InlineData("Second", 0, 0, 1)]
+ [InlineData("Seconds", 0, 0, 2)]
+ public void Convert_works(string resource, int hours, int minutes, int seconds)
+ {
+ var timeRemaining = new TimeSpan(hours, minutes, seconds);
+ var converter = new TimeRemainingConverter();
+
+ var result = converter.Convert(
+ timeRemaining,
+ targetType: null,
+ parameter: null,
+ CultureInfo.InvariantCulture);
+
+ Assert.Equal(
+ string.Format(
+ Resources.ResourceManager.GetString("Progress_TimeRemaining_" + resource),
+ hours,
+ minutes,
+ seconds),
+ result);
+ }
+ }
+}
diff --git a/ImageResizer/tools/packages.config b/ImageResizer/tools/packages.config
new file mode 100644
index 000000000000..0b908d49926c
--- /dev/null
+++ b/ImageResizer/tools/packages.config
@@ -0,0 +1,4 @@
+
+
+
+