Last active
November 12, 2020 15:01
-
-
Save JohnLBevan/3f8c8ee11becad4b9a56d3f6717ac402 to your computer and use it in GitHub Desktop.
Google Backup and Sync - Resize Photos For Upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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