Taking Screenshots

Taking simple screenshots in VapourSynth is very easy. If you're using a previewer, you can likely use that instead, but it might still be useful to know how to take screenshots via VapourSynth directly.

We recommend using awsmfunc.ScreenGen. This has two advantages:

  1. You save frame numbers and can easily reference these again, e.g. if you want to redo your screenshots.
  2. It takes care of proper conversion and compression for you, which might not be the case with some previewers (e.g. VSEdit).

To use ScreenGen, from within the directory containing your VapourSynth script, create a file called screens.txt with the frame numbers you'd like to screenshot, e.g.


Then, at the bottom of your VapourSynth script, put

awf.ScreenGen(src, "Screenshots", "a")

a is what is put after the frame number. This is useful for staying organized and sorting screenshots, as well as preventing unnecessary overwriting of screenshots.

Now, run your script in the command line (or reload in a previewer):

python vapoursynth_script.vpy

Done! Your screenshots should now be in the Screenshots folder.

Comparing Source vs. Encode

Comparing the source against your encode allows potential downloaders to judge the quality of your encode easily. When taking these, it is important to include the frame types you are comparing, as e.g. comparing two I frames will lead to extremely favorable results. You can do this using awsmfunc.FrameInfo:

src = awf.FrameInfo(src, "Source")
encode = awf.FrameInfo(encode, "Encode")

If you'd like to compare these in your previewer, it's recommended to interleave them:

out = core.std.Interleave([src, encode])

However, if you're taking your screenshots with ScreenGen, it's easier not to do that and just run a ScreenGen call:

src = awf.FrameInfo(src, "Source")
encode = awf.FrameInfo(encode, "Encode")
awf.ScreenGen([src, encode], "Screenshots")

By default, this will generate src screenshots with the suffix "a", and encode screenshots with the suffix "b". This will allow you to sort your folder by name and have every source screenshot followed by an encode screenshot, making uploading easier.

To use custom suffixes, you can use the suffix argument:

awf.ScreenGen([src, encode], "Screenshots", suffix=["src","enc"])

HDR comparisons

For comparing an HDR source to an HDR encode, it's recommended to tonemap. This process is destructive, but you should still be able to tell what's warped, smoothed etc.

The recommended function for this is awsmfunc.DynamicTonemap:

src = awf.DynamicTonemap(src)
encode = awf.DynamicTonemap(encode, reference=src)

The reference=src in the second tonemap makes sure that the tonemapping is consistent across the two.

Optional: For better quality tonemapping, ensure that you have installed vs-placebo.

Choosing frames

When taking screenshots, it is important to not make your encode look deceptively transparent. To do so, you need to make sure you're screenshotting the proper frame types as well as content-wise differing kinds of frames.

Luckily, there's not a lot to remember here:

  • Your encode's screenshots should always be B type frames.
  • Your source's screenshots should never be I type frames.
  • Your comparisons should include dark scenes, bright scenes, close-up shots, long-range shots, static scenes, high action scenes, and whatever you have in-between.

Comparing Different Sources

When comparing different sources, you should proceed similarly to comparing source vs. encode. However, you'll likely encounter differing crops, resolutions or tints, all of which get in the way of comparing.

For differing crops, simply add borders back:

src_b = src_b.std.AddBorders(left=X, right=Y, top=Z, bottom=A)

If doing this leads to an offset of the image content, you should resize to 4:4:4 so you can add uneven borders. For example, if you want to add 1 pixel tall black bars to the top and bottom:

src_b = src_b.resize.Spline36(format=vs.YUV444P8, dither_type="error_diffusion")
src_b = src_b.std.AddBorders(top=1, bottom=1)

For differing resolutions, it's recommended to use a simple spline resize1:

src_b = src_b.resize.Spline36(src_a.width, src_a.height, dither_type="error_diffusion")

If one source is HDR and the other one is SDR, you can use awsmfunc.DynamicTonemap:

src_b = awf.DynamicTonemap(src_b)

For different tints, refer to the tinting chapter.


It's important to make sure you're resizing to the appropriate resolution here; if you're comparing for a 1080p encode, you'd obviously compare at 1080p, whereas if you're comparing for the sake of figuring out which source is better, you'll want to upscale the lower resolution source to match the higher resolution.