133 lines
4.3 KiB
Markdown
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
|
|
```
|