Files
Video-Processing-Scripts/skill/Get-LastFrame.md
T

133 lines
4.3 KiB
Markdown

# Get-LastFrame.ps1
Extracts a specific frame of a video file to a PNG image.
## Parameters
- **`-Video`** (required): Path to input video file
- **`-Image`** (required): Path to output PNG image file. Supports a printf-style numbering token like [Get-FramesRange.ps1](Get-FramesRange.md) — see [Filename Pattern](#filename-pattern). The output directory is created when it does not exist.
- **`-Frame`** (optional): 0-based frame index to extract (default: -1)
- Positive values: Direct frame index (e.g., 0 = first frame, 100 = frame 100)
- Negative values: Count from the end (e.g., -1 = last frame, -2 = second-to-last)
- Values are automatically clamped to valid range (0 to total frames - 1)
## Filename Pattern
`-Image` may contain a printf-style numbering token, which is replaced with the **actual 0-based frame index that was extracted** — after `-Frame` has been resolved, so negative indices produce the real frame number:
| Token | Meaning | Frame 99 | Frame 7 |
| --- | --- | --- | --- |
| `%d` | No padding | `99` | `7` |
| `%04d` | Zero-padded to 4 digits | `0099` | `0007` |
| `%06d` | Zero-padded to 6 digits | `000099` | `000007` |
A path without a token is used **literally**, so existing commands such as `-Image last_frame.png` are unaffected (only one frame is produced, so no numbering is needed).
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image "frame_%04d.png"
# 100-frame video -> frame_0099.png
```
When the pattern resolves, the script reports the final name:
```text
Total frames: 100 - extracting frame index 99
Output pattern resolved to: frame_0099.png
Frame saved to: frame_0099.png
```
**Note:** the token is expanded by the script, not by ffmpeg. ffmpeg would treat `%04d` in an output path as an image-sequence counter starting at `1` (writing `frame_0001.png` regardless of which frame was selected); expanding it here guarantees the number is the real video frame index, matching [Get-FramesRange.ps1](Get-FramesRange.md).
## Examples
**Extract last frame:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image last_frame.png
```
**Extract specific frame:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image frame_100.png -Frame 100
```
**Extract first frame:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image first_frame.png -Frame 0
```
**Extract second-to-last frame:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image second_last.png -Frame -2
```
**Extract 10th frame from the end:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image frame_minus_10.png -Frame -10
```
**Using absolute paths:**
```powershell
.\Get-LastFrame.ps1 -Video "C:\Videos\input.mp4" -Image "C:\Frames\output.png" -Frame 50
```
**Filename pattern with the frame number:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image "frame_%04d.png"
# If video has 100 frames, creates: frame_0099.png
```
**Full output path with a pattern (directory is created if missing):**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image "C:\Output\frame_%04d.png" -Frame 50
# Creates: C:\Output\frame_0050.png
```
**Pattern with a negative frame index:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image "p_%06d.png" -Frame -2
# If video has 100 frames, creates: p_000098.png
```
**Pattern without padding:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image "f_%d.png" -Frame 7
# Creates: f_7.png
```
## Existing Files
An existing output PNG is **replaced** without a prompt. ffmpeg runs with `-y`.
- When `-Image` contains a numbering token such as `%04d`, the file replaced is the **resolved** name, not the pattern. For example, `-Image f_%04d.png -Frame 3` writes and replaces `f_0003.png`.
- If the output folder does not exist, it is created. With `-WhatIf` it is only reported.
- Use `-WhatIf` first, or write to a new name.
## Safe Execution
This script supports `-WhatIf` and `-Confirm` for safe execution:
- **`-WhatIf`**: Simulate the operation without actually extracting the frame. Shows the resolved output name and what would be extracted; no output directory is created.
- **`-Confirm`**: Prompt for confirmation before extracting the frame.
**Simulate without extracting:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image frame.png -WhatIf
```
**Prompt before extraction:**
```powershell
.\Get-LastFrame.ps1 -Video video.mp4 -Image frame.png -Frame 100 -Confirm
```