Skip to content

Instantly share code, notes, and snippets.

@jkotra
Created December 6, 2019 20:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkotra/c2b8b785286f7cff7152ca322a9cd4dc to your computer and use it in GitHub Desktop.
Save jkotra/c2b8b785286f7cff7152ca322a9cd4dc to your computer and use it in GitHub Desktop.
Vpy pillow
#vsshow.py
import vapoursynth as vs
from ctypes import *
from PIL import Image
def show(core, clip, frame_number, vflip=1):
format = clip.format.id
width = clip.width
height = clip.height
if format == vs.GRAY16:
clip = core.resize.Point(clip, width, height, vs.GRAY8)
if format != vs.GRAY8 and format != vs.RGB24:
clip = core.resize.Bicubic(clip, width, height, vs.COMPATBGR32)
format = clip.format.id
planes = range(clip.format.num_planes)
frame = clip.get_frame(frame_number)
data = [(frame.get_read_ptr(p), frame.get_stride(p)) for p in planes]
buff = [b'\0' * data[p][1] * height for p in planes]
for p in planes:
memmove(buff[p], data[p][0], data[p][1] * height)
if format == vs.COMPATBGR32:
mode, src = 'RGBA', 'BGRA'
else:
mode, src = 'L', 'L'
img = [Image.frombytes(mode, (width, height), buff[p], 'raw', src,
data[p][1], vflip) for p in planes]
if len(planes) != 1:
img = Image.merge('RGB', (img[2], img[0], img[1]))
else:
img = img[0]
img.show()
@rlaphoenix
Copy link

rlaphoenix commented Dec 1, 2022

This no longer seems to work on newer VapourSynth revisions. For whatever reason it's failing at the Image.frombytes call with ValueError: cannot decode image data. This is happening on all three planes of a vs.RGB24 input frame.

An alternative is by using Numpy as a middleman (still only supports GRAY8 or RGB24!)

clip = clip.resize.Spline16(format=vs.RGB24, matrix_in_s="470bg")

frame = clip.get_frame(5000)
array = np.dstack([
    np.asarray(frame[p])
    for p in [0,1,2]
])

pil_img = Image.fromarray(array)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment