Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Last active November 12, 2020 15:01
Show Gist options
  • Save JohnLBevan/3f8c8ee11becad4b9a56d3f6717ac402 to your computer and use it in GitHub Desktop.
Save JohnLBevan/3f8c8ee11becad4b9a56d3f6717ac402 to your computer and use it in GitHub Desktop.
Google Backup and Sync - Resize Photos For Upload
# hackaround for https://support.google.com/drive/thread/35629075?hl=en
# Warnings:
# I've not put much sanity wraping around this solution as I just needed a quick fix... there are some risks / caveats / room for improvement
# The save method will overwrite existing files with the same name / directory without prompting. Adding a check before saving is trivial / you could add Force, ShouldProcess, NoClobber, etc options as needed.
# You can't use the `NewNameMask = '{0}{3}{1}{2}'` (i.e. overwrite the source file), as we keep the file handle of the source open until after the resized image is changed. If that's a need, it's fairly simple to correct; I've just not needed the extra effort
Function Convert-ImageSize {
[CmdletBinding()]
Param (
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string[]]$Path
,
[Parameter()]
[int]$MinWidthInPixels = 256
,
[Parameter()]
[int]$MinHeightInPixels = 256
,
# Format mask:
# - 0: Original Directory
# - 1: Orignal Filename (without extension)
# - 2: Original Extension (including period)
# - 3: Directory separator char
# Default: "{0}{3}{1}.resized{2}" - given c:\example\image.jpg, creates c:\example\image.resized.jpg
# Example: "d:\temp\{1}{2}" - given c:\example\image.jpg, creates d:\temp\image.jpg
[Parameter()]
[string]$NewNameMask = "{0}{3}{1}.resized{2}"
)
Begin {
Add-Type -AssemblyName 'System.Drawing' | Out-Null
}
Process {
ForEach ($imagePath in $Path) {
try {
Write-Verbose "Processing '$imagePath'"
$image = [System.Drawing.Image]::FromFile( $imagePath )
if ( ($image.Width -lt $MinWidthInPixels) -or ($image.Height -lt $MinHeightInPixels) ) {
$scale = [Math]::Max(($MinWidthInPixels / $image.Width), ($MinHeightInPixels / $image.Height))
$resized = [System.Drawing.Bitmap]::new($image, [System.Drawing.Size]::new( $image.Width * $scale, $image.Height * $scale ))
try {
$fi = [System.IO.FileInfo]::new($imagePath)
$fn = $NewNameMask -f $fi.Directory.FullName, $fi.BaseName, $fi.Extension, [System.IO.Path]::DirectorySeparatorChar
$resized.Save($fn, $image.RawFormat)
Write-Verbose "- Resized to ($($resized.Width) x $($resized.Height))"
} finally {
$resized.Dispose()
}
} else {
Write-Verbose " - No need to resize"
}
} catch {
Write-Verbose " - Skipped due to error: ($($_.Exception.Message))"
Write-Error ($_.Exception.Message) #include this so ErrorActionPreference can be used to control whether we stop the first time we hit an error (maybe the file wasn't an image file?), or continue regardless... We could get more creative in what control's allowed here (e.g. what type of exceptions cause the process to stop), but feel free to tweak this script to your needs
} finally {
if ($null -ne $image) {
$image.Dispose()
}
}
}
}
}
# example usage
# Get-ChildItem 'c:\some\path\myGoogleDrivePhotos' -Recurse -Include '*.jpg','*.png','*.jpeg' | Convert-ImageSize -Verbose -ErrorAction SilentlyContinue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment