71 lines
1.8 KiB
PowerShell
71 lines
1.8 KiB
PowerShell
|
|
param(
|
||
|
|
[Parameter(Mandatory=$true)][string]$InputPath,
|
||
|
|
[Parameter(Mandatory=$true)][string]$OutputPath,
|
||
|
|
[string]$BackupPath = "",
|
||
|
|
[int]$AlphaThreshold = 1,
|
||
|
|
[int]$Padding = 0
|
||
|
|
)
|
||
|
|
|
||
|
|
if (!(Test-Path -LiteralPath $InputPath)) {
|
||
|
|
throw "Input file not found: $InputPath"
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($BackupPath -ne "") {
|
||
|
|
Copy-Item -LiteralPath $InputPath -Destination $BackupPath -Force
|
||
|
|
}
|
||
|
|
|
||
|
|
Add-Type -AssemblyName System.Drawing
|
||
|
|
|
||
|
|
# Load from stream to avoid locking
|
||
|
|
$fs = [System.IO.File]::Open($InputPath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
|
||
|
|
try {
|
||
|
|
$bmp = New-Object System.Drawing.Bitmap($fs)
|
||
|
|
} finally {
|
||
|
|
$fs.Dispose()
|
||
|
|
}
|
||
|
|
|
||
|
|
$minX = $bmp.Width
|
||
|
|
$minY = $bmp.Height
|
||
|
|
$maxX = -1
|
||
|
|
$maxY = -1
|
||
|
|
|
||
|
|
for ($y = 0; $y -lt $bmp.Height; $y++) {
|
||
|
|
for ($x = 0; $x -lt $bmp.Width; $x++) {
|
||
|
|
$c = $bmp.GetPixel($x, $y)
|
||
|
|
if ($c.A -ge $AlphaThreshold) {
|
||
|
|
if ($x -lt $minX) { $minX = $x }
|
||
|
|
if ($y -lt $minY) { $minY = $y }
|
||
|
|
if ($x -gt $maxX) { $maxX = $x }
|
||
|
|
if ($y -gt $maxY) { $maxY = $y }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($maxX -lt 0 -or $maxY -lt 0) {
|
||
|
|
# No non-transparent pixels, just copy input
|
||
|
|
$bmp.Dispose()
|
||
|
|
Copy-Item -LiteralPath $InputPath -Destination $OutputPath -Force
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
$minX = [math]::Max(0, $minX - $Padding)
|
||
|
|
$minY = [math]::Max(0, $minY - $Padding)
|
||
|
|
$maxX = [math]::Min($bmp.Width - 1, $maxX + $Padding)
|
||
|
|
$maxY = [math]::Min($bmp.Height - 1, $maxY + $Padding)
|
||
|
|
|
||
|
|
$newW = $maxX - $minX + 1
|
||
|
|
$newH = $maxY - $minY + 1
|
||
|
|
|
||
|
|
$rect = New-Object System.Drawing.Rectangle($minX, $minY, $newW, $newH)
|
||
|
|
$cropped = $bmp.Clone($rect, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
|
||
|
|
|
||
|
|
$tmp = "$OutputPath.tmp"
|
||
|
|
try {
|
||
|
|
$cropped.Save($tmp, [System.Drawing.Imaging.ImageFormat]::Png)
|
||
|
|
} finally {
|
||
|
|
$cropped.Dispose()
|
||
|
|
$bmp.Dispose()
|
||
|
|
}
|
||
|
|
|
||
|
|
Move-Item -LiteralPath $tmp -Destination $OutputPath -Force
|