Answers.Body: <p>The key is using the overlay filter to embed the subtitles on a transparent or fixed-color background. Adjust the <code>size</code> and <code>rate</code> to match your input video.</p>
  <h2>Transparent version</h2>
  <p><code>ffmpeg -i my_video.mkv -f lavfi -i &quot;color=size=1920x1080:rate=23.98:color=black@0.0,format=rgba&quot; -filter_complex &quot;[1:v][0:s]overlay,mpdecimate[out]&quot; -map &quot;[out]&quot; -an -vsync vfr frames_%04d.png</code></p>
  <p>This means:</p>
  <ul>
  <li><code>-i my_video.mkv</code>: Input filename</li>
  <li><code>-f lavfi</code>: The next input is a <a href="https://ffmpeg.org/ffmpeg-devices.html#lavfi" rel="nofollow noreferrer"><code>libavfilter</code> graph specification</a>.</li>
  <li><code>-i &quot;color=size=1920x1080:rate=23.98:color=black@0.0,format=rgba&quot;</code>: Produce a video stream that is 1080p with a 23.98 fps frame rate. The <code>@0.0</code> specifier indicates a fully-transparent color, which requires <code>format=rgba</code>.</li>
  <li><code>-filter_complex &quot;[1:v][0:s]overlay,mpdecimate[out]&quot;</code>: Overlay the first subtitle stream in input source 0 (the original video) atop the first video stream in input source 1 (the <code>lavfi</code> output). Decimate the output frames by removing all duplicates. Output a stream named &quot;out&quot;.</li>
  <li><code>-map &quot;[out]&quot;</code>: Use the stream named &quot;out&quot; in the final output.</li>
  <li><code>-an</code>: Audio is disabled.</li>
  <li><code>-vsync vfr</code>: Drop frame timestamps so that each unique frame, in sequence, is output only once.</li>
  <li><code>frames_%04d.png</code>: Output frames_0000.png where <code>0000</code> is an increasing number. If you expect more than 10000 unique frames, increase <code>%04d</code> to <code>%05d</code> for 5 digits, etc.</li>
  </ul>
  <h2>Non-transparent version (much faster?)</h2>
  <p>If you can tolerate, or prefer, a non-transparent background, the process may run much faster. It goes 3-4x faster on my machine. Just remove the <code>@0.0,format=rgba</code> part.</p>
  <p><code>ffmpeg -i my_video.mkv -f lavfi -i &quot;color=size=1920x1080:rate=23.98:color=black&quot; -filter_complex &quot;[1:v][0:s]overlay,mpdecimate[out]&quot; -map &quot;[out]&quot; -an -vsync vfr frames_%04d.png</code></p>
  <h2>Output</h2>
  <p>You'll get a PNG for each frame of unique subtitle content, plus a frame of black/transparent in between. Maybe there's a way to filter out those blank frames, but for now I can handle that outside ffmpeg.</p>
  <h2>Caution</h2>
  <p>If you add <code>-t</code> to limit the time of the extracted subtitles, be sure to add it twice: once after the <code>-i</code> for the input video and once after the <code>-i</code> for the black frames &amp; subtitles. This will ensure that both streams terminate at the specified time; otherwise one stream will keep going for the full video duration.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-11-28T02:53:06.240Z
Answers.LastActivityDate: 2024-03-23T15:06:44.793Z
Answers.LastEditDate: 2024-03-23T15:06:44.793Z
Answers.UserDisplayName: Ethan T
Body: <p>I need to extract bitmap-based subtitles to a standard image format like PNG or BMP. Preserving transparency would be a bonus. I don't need to convert to text, and I don't want a subtitle-specific format.</p>
  
Tags: <ffmpeg><subtitles>
Title: How do you extract bitmap subtitles to a standard image format using ffmpeg?
UserDisplayName: Ethan T
ThreadText: # How do you extract bitmap subtitles to a standard image format using ffmpeg?
  
  (Asked by: username_0 on 2023-11-28)
  
  I need to extract bitmap-based subtitles to a standard image format like PNG or BMP. Preserving transparency would be a bonus. I don't need to convert to text, and I don't want a subtitle-specific format.
  
  **Tags:** ffmpeg, subtitles
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2023-11-28. Score: 2
  
  The key is using the overlay filter to embed the subtitles on a transparent or fixed-color background. Adjust the `size` and `rate` to match your input video.
  
  ## Transparent version
  
  `ffmpeg -i my_video.mkv -f lavfi -i "color=size=1920x1080:rate=23.98:color=black@0.0,format=rgba" -filter_complex "[1:v][0:s]overlay,mpdecimate[out]" -map "[out]" -an -vsync vfr frames_%04d.png`
  
  This means:
  
  * `-i my_video.mkv`: Input filename
  * `-f lavfi`: The next input is a [`libavfilter` graph specification](https://ffmpeg.org/ffmpeg-devices.html#lavfi).
  * `-i "color=size=1920x1080:rate=23.98:color=black@0.0,format=rgba"`: Produce a video stream that is 1080p with a 23.98 fps frame rate. The `@0.0` specifier indicates a fully-transparent color, which requires `format=rgba`.
  * `-filter_complex "[1:v][0:s]overlay,mpdecimate[out]"`: Overlay the first subtitle stream in input source 0 (the original video) atop the first video stream in input source 1 (the `lavfi` output). Decimate the output frames by removing all duplicates. Output a stream named "out".
  * `-map "[out]"`: Use the stream named "out" in the final output.
  * `-an`: Audio is disabled.
  * `-vsync vfr`: Drop frame timestamps so that each unique frame, in sequence, is output only once.
  * `frames_%04d.png`: Output frames\_0000.png where `0000` is an increasing number. If you expect more than 10000 unique frames, increase `%04d` to `%05d` for 5 digits, etc.
  
  ## Non-transparent version (much faster?)
  
  If you can tolerate, or prefer, a non-transparent background, the process may run much faster. It goes 3-4x faster on my machine. Just remove the `@0.0,format=rgba` part.
  
  `ffmpeg -i my_video.mkv -f lavfi -i "color=size=1920x1080:rate=23.98:color=black" -filter_complex "[1:v][0:s]overlay,mpdecimate[out]" -map "[out]" -an -vsync vfr frames_%04d.png`
  
  ## Output
  
  You'll get a PNG for each frame of unique subtitle content, plus a frame of black/transparent in between. Maybe there's a way to filter out those blank frames, but for now I can handle that outside ffmpeg.
  
  ## Caution
  
  If you add `-t` to limit the time of the extracted subtitles, be sure to add it twice: once after the `-i` for the input video and once after the `-i` for the black frames & subtitles. This will ensure that both streams terminate at the specified time; otherwise one stream will keep going for the full video duration.
  
  
  ---
  
  