param( [Parameter(Mandatory = $true)][string]$Output, [Parameter(Mandatory = $true)][string[]]$InputPaths ) $ErrorActionPreference = 'Stop' Add-Type -AssemblyName System.Drawing if ($InputPaths.Count -lt 2) { throw 'Contact sheet requires at least two images.' } $images = @() try { foreach ($inputPath in $InputPaths) { $resolved = (Resolve-Path -LiteralPath $inputPath).Path $images += [System.Drawing.Bitmap]::FromFile($resolved) } $width = ($images | Measure-Object -Property Width -Sum).Sum $height = ($images | Measure-Object -Property Height -Maximum).Maximum $canvas = [System.Drawing.Bitmap]::new($width, $height, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb) try { $graphics = [System.Drawing.Graphics]::FromImage($canvas) try { $graphics.Clear([System.Drawing.Color]::FromArgb(247, 240, 228)) $offsetX = 0 foreach ($image in $images) { $graphics.DrawImageUnscaled($image, $offsetX, 0) $offsetX += $image.Width } } finally { $graphics.Dispose() } $outputPath = [System.IO.Path]::GetFullPath($Output) [System.IO.Directory]::CreateDirectory([System.IO.Path]::GetDirectoryName($outputPath)) | Out-Null $canvas.Save($outputPath, [System.Drawing.Imaging.ImageFormat]::Png) Write-Output "CONTACT-SHEET $outputPath" } finally { $canvas.Dispose() } } finally { foreach ($image in $images) { $image.Dispose() } }