Refactor Crop-Clips.ps1 to use table-driven crop profiles for LTX-2, Kling and Wan resolutions, add -Vertical parameter to Create-PillarBox.ps1 for 9:16 portrait output from square sources with horizontal bars, update Resolve-Size to check both dimensions when selecting presets and transpose named sizes in portrait mode, and update README to reflect consolidated cropping functionality
This commit is contained in:
1 parent
274dac5786
commit
b823259ab1
3 files changed
+111
-86
No files matched your search
+55
-16
@@ -7,6 +7,7 @@
|
||||
Path to the output video file. Can be absolute or relative to current directory. .mp4 extension is added if not provided.
|
||||
If omitted, defaults to the source filename with the -Effect value (lowercased) appended after a dash,
|
||||
saved alongside the source (e.g. video.mp4 + -Effect black -> video-black.mp4).
|
||||
When -Vertical is used, '-vertical' is appended after the effect (e.g. video-black-vertical.mp4).
|
||||
.PARAMETER Effect
|
||||
The effect to apply to the side bars. Possible values are:
|
||||
black: The side bars will be solid black (#000000).
|
||||
@@ -18,8 +19,14 @@
|
||||
standard: Creates softly blurred side bars generated from the video itself, with a subtle zoom to fill the 16:9 frame.
|
||||
dark: Produces blurred side bars with reduced brightness, creating a darker, more contrasted background that enhances focus on the main video.
|
||||
gaussian: Generates smooth, high‑quality Gaussian‑blurred side bars for a clean, professional broadcast-style background.
|
||||
.PARAMETER Vertical
|
||||
Only valid when the source video has a square (1:1) resolution. When present, the output is a 9:16 portrait
|
||||
video with the bars on the top and bottom instead of the default 16:9 landscape output with bars on the sides.
|
||||
Named -Size presets are interpreted as portrait sizes (e.g. 1080p -> 1080x1920, 4K -> 2160x3840).
|
||||
Throws when the source video is not square.
|
||||
.PARAMETER Size
|
||||
Size of the output video. Uses the input video's closest size that will fit the 16:9 aspect ratio if not specified.
|
||||
Size of the output video. Uses the input video's closest size that will fit the 16:9 aspect ratio if not specified
|
||||
(9:16 when -Vertical is used).
|
||||
Possible values: 480p, 720p, 1080p, HD, 1440p, 2K, 2160p, 4K, or custom size in format "width:height".
|
||||
.PARAMETER FPS
|
||||
Frames per second for the output video. Uses the input video's FPS if not specified.
|
||||
@@ -33,6 +40,7 @@
|
||||
Creates a pillar-boxed video file from a video file. Will add black bars to the sides of the video to match 16:9 aspect ratio.
|
||||
The black bars will be verticals on each side of the output video if the source video is more portrait-like (e.g. 9:16).
|
||||
Otherwise, the black bars will be horizontal on the top and bottom of the output video.
|
||||
With -Vertical (square sources only), the output frame is 9:16 instead and the bars are horizontal on the top and bottom.
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
@@ -45,6 +53,9 @@ param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$Effect,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Vertical,
|
||||
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$Size = $null,
|
||||
|
||||
@@ -136,7 +147,12 @@ function Resolve-Size {
|
||||
[int]$SourceWidth,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[int]$SourceHeight
|
||||
[int]$SourceHeight,
|
||||
|
||||
# When set, the output frame is 9:16 (portrait) instead of 16:9: named presets
|
||||
# are transposed (1080p -> 1080x1920) and the computed frame is portrait.
|
||||
[Parameter(Mandatory = $false)]
|
||||
[switch]$Vertical
|
||||
)
|
||||
|
||||
# Standard 16:9 sizes (largest first only matters for closest-fit lookup)
|
||||
@@ -154,6 +170,9 @@ function Resolve-Size {
|
||||
if ($Value) {
|
||||
$named = $standards | Where-Object { $_.Name -ieq $Value } | Select-Object -First 1
|
||||
if ($named) {
|
||||
if ($Vertical) {
|
||||
return [pscustomobject]@{ Width = $named.Height; Height = $named.Width }
|
||||
}
|
||||
return [pscustomobject]@{ Width = $named.Width; Height = $named.Height }
|
||||
}
|
||||
|
||||
@@ -164,29 +183,41 @@ function Resolve-Size {
|
||||
throw "Invalid -Size value: $Value. Use a named preset (480p, 720p, 1080p, HD, 1440p, 2K, 2160p, 4K) or 'width:height'."
|
||||
}
|
||||
|
||||
# Pick the smallest standard 16:9 preset whose longer side (width) is at least
|
||||
# the source's longer side. The foreground is scaled down with
|
||||
# 'force_original_aspect_ratio=decrease', so the source is allowed to shrink
|
||||
# to fit; we only need the preset to be "big enough" relative to the source's
|
||||
# largest dimension. This produces the documented behavior:
|
||||
# Pick the smallest standard 16:9 preset that holds the source's bounding box
|
||||
# once that box is laid out in the frame's orientation: the preset's long side
|
||||
# (width) must be at least the source's long side AND the preset's short side
|
||||
# (height) must be at least the source's short side. Checking both sides matters
|
||||
# for square-ish sources: a 1080x1080 source fits 1920x1080 at full resolution,
|
||||
# while 1280x720 would force it down to 720x720.
|
||||
# This produces the documented behavior:
|
||||
# 1080x1920 portrait -> 1920x1080 (vertical bars on either side)
|
||||
# 720x1280 portrait -> 1280x720
|
||||
# 1080x1080 square -> 1920x1080 (vertical bars, source kept at 1080x1080)
|
||||
# 2560x1080 landscape -> 2560x1440 (horizontal bars top/bottom)
|
||||
# With -Vertical the same preset is used transposed (e.g. 1080x1080 -> 1080x1920).
|
||||
$longSide = [math]::Max($SourceWidth, $SourceHeight)
|
||||
$shortSide = [math]::Min($SourceWidth, $SourceHeight)
|
||||
|
||||
$unique = $standards | Sort-Object { $_.Width } -Unique
|
||||
foreach ($s in $unique) {
|
||||
if ($s.Width -ge $longSide) {
|
||||
if ($s.Width -ge $longSide -and $s.Height -ge $shortSide) {
|
||||
if ($Vertical) {
|
||||
return [pscustomobject]@{ Width = $s.Height; Height = $s.Width }
|
||||
}
|
||||
return [pscustomobject]@{ Width = $s.Width; Height = $s.Height }
|
||||
}
|
||||
}
|
||||
|
||||
# Source larger than any standard preset: build a 16:9 frame whose width
|
||||
# matches the source's longer side (rounded to even).
|
||||
$w = $longSide + ($longSide % 2)
|
||||
$h = [int][math]::Ceiling($w * 9.0 / 16.0)
|
||||
if ($h % 2) { $h++ }
|
||||
return [pscustomobject]@{ Width = $w; Height = $h }
|
||||
# Source larger than any standard preset: build a 16:9 (or 9:16) frame that
|
||||
# holds the source's bounding box, rounded to even dimensions.
|
||||
$long = [math]::Max($longSide, [int][math]::Ceiling($shortSide * 16.0 / 9.0))
|
||||
$short = [math]::Max($shortSide, [int][math]::Ceiling($long * 9.0 / 16.0))
|
||||
if ($long % 2) { $long++ }
|
||||
if ($short % 2) { $short++ }
|
||||
if ($Vertical) {
|
||||
return [pscustomobject]@{ Width = $short; Height = $long }
|
||||
}
|
||||
return [pscustomobject]@{ Width = $long; Height = $short }
|
||||
}
|
||||
|
||||
# Validate -Effect first so it can be used in the default -Target name.
|
||||
@@ -231,11 +262,13 @@ $sourceFull = (Resolve-Path -LiteralPath $Source).Path
|
||||
# (e.g. C:\clips\video.mp4 + -Effect Black -> C:\clips\video-black.mp4).
|
||||
# For 'color:RRGGBB', the colon is replaced with a dash to keep the filename valid
|
||||
# (e.g. -Effect color:FFFF00 -> video-color-ffff00.mp4).
|
||||
# With -Vertical, '-vertical' is appended last (e.g. video-black-vertical.mp4).
|
||||
if ([string]::IsNullOrWhiteSpace($Target)) {
|
||||
$srcDir = [System.IO.Path]::GetDirectoryName($sourceFull)
|
||||
$srcBase = [System.IO.Path]::GetFileNameWithoutExtension($sourceFull)
|
||||
$effectForName = $effectLower -replace ':', '-'
|
||||
$Target = Join-Path $srcDir "$srcBase-$effectForName.mp4"
|
||||
$verticalForName = if ($Vertical) { '-vertical' } else { '' }
|
||||
$Target = Join-Path $srcDir "$srcBase-$effectForName$verticalForName.mp4"
|
||||
}
|
||||
elseif (-not [System.IO.Path]::GetExtension($Target)) {
|
||||
$Target = "$Target.mp4"
|
||||
@@ -271,7 +304,13 @@ $inQuality = Format-Quality -BitRate $inInfo.BitRate
|
||||
$inAudioText = if ($inInfo.HasAudio) { 'yes' } else { 'no' }
|
||||
Write-Host "Input : Filename=$($inInfo.FileName) Resolution=$inRes FPS=$inFpsText Quality=$inQuality Audio=$inAudioText"
|
||||
|
||||
$outSize = Resolve-Size -Value $Size -SourceWidth $inInfo.Width -SourceHeight $inInfo.Height
|
||||
# -Vertical produces a 9:16 output frame (bars on top and bottom) and is only
|
||||
# meaningful for square sources, where the 16:9 / 9:16 choice is otherwise arbitrary.
|
||||
if ($Vertical -and $inInfo.Width -ne $inInfo.Height) {
|
||||
throw "-Vertical requires a square (1:1) source video, but '$($inInfo.FileName)' is $inRes."
|
||||
}
|
||||
|
||||
$outSize = Resolve-Size -Value $Size -SourceWidth $inInfo.Width -SourceHeight $inInfo.Height -Vertical:$Vertical
|
||||
$outWidth = $outSize.Width
|
||||
$outHeight = $outSize.Height
|
||||
|
||||
|
||||
Reference in new issue
Block a user