在pyvista中保存屏幕截图,包括交互/旋转

2024-04-30 01:29:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在寻找一种方法,在pyvista中的交互期间有效地捕获帧缓冲区,这样我就可以在模型在屏幕上移动之后生成视频

我遇到的问题是,当我单击屏幕与查看器/绘图仪交互时,当按下鼠标按钮且模型移动到下一个位置时,不会写入任何帧。这会导致视频中出现“急促”的动作

有没有一种方法可以绕过这种行为来有效地执行诸如绘图仪窗口的屏幕截图之类的操作,即使在被操纵时也是如此?可能通过直接访问帧缓冲区或类似的方式

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import pyvista as pv
import numpy as np
from pyvista import examples

import matplotlib as mpl
import matplotlib.pyplot as plt

px = int(round(1920*0.4))
py = int(round(1000*0.4))

mesh = examples.download_st_helens().warp_by_scalar()

p = pv.Plotter()
p.set_background(color='k')
cmap = mpl.cm.get_cmap('viridis')
p.add_mesh(mesh, lighting=True, texture=False, cmap=cmap, smooth_shading=True)
p.show_grid()
p.show(window_size=[px,py], auto_close=False, interactive_update=True)
p.render()
p.open_movie('anim.mp4',framerate=60)

i=0
while (i<100):
    i+=1
    p.write_frame()
    print(i)

p.close()

enter image description here


Tags: 方法模型importtrue视频屏幕matplotlibas
1条回答
网友
1楼 · 发布于 2024-04-30 01:29:43

我在纯VTK中添加了一个示例,其中立方体旋转,并通过旋转捕获平滑视频。之后,交互器启动,用户可以随后与场景交互

import os
import vtk
import numpy as np

def vtkRotationMovie(renderWindow, filename='c:/test.avi'):
  global degrees
  degrees = 0

  windowToImageFilter = vtk.vtkWindowToImageFilter()
  windowToImageFilter.SetInput(renderWindow)
  windowToImageFilter.SetInputBufferTypeToRGB()
  windowToImageFilter.ReadFrontBufferOff()
  windowToImageFilter.Update()

  if os.name == 'nt':
    writer = vtk.vtkAVIWriter()
  else:
    writer = vtk.vtkOggTheoraWriter()
  writer.SetInputConnection(windowToImageFilter.GetOutputPort())
  writer.SetRate(10) # Not needed for Ogg

  try:
    os.remove(filename)
  except OSError:
    pass
  writer.SetFileName(filename)
  writer.Start()

  timerId = renderWindow.GetInteractor().CreateRepeatingTimer(50)
  def cb(interactor, event):
    global degrees
    step = 5
    if (degrees > 359):
      interactor.DestroyTimer(timerId)
      writer.End()
      return
    interactor.GetRenderWindow().Render()
    cam = interactor.GetRenderWindow().GetRenderers().GetFirstRenderer().GetActiveCamera()
    cam.Azimuth(step)
    cam.OrthogonalizeViewUp()
    windowToImageFilter.Modified()
    writer.Write()
    degrees = degrees + step
  renderWindow.GetInteractor().AddObserver('TimerEvent', cb)
  renderWindow.GetInteractor().Start()

# create a rendering window and renderer
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)

# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# create cube
cube = vtk.vtkCubeSource()

# mapper
cubeMapper = vtk.vtkPolyDataMapper()
cubeMapper.SetInputConnection(cube.GetOutputPort())

# actor
cubeActor = vtk.vtkActor()
cubeActor.SetMapper(cubeMapper)

# assign actor to the renderer
ren.AddActor(cubeActor)
ren.SetBackground(.3,.2,.1)
# enable user interface interactor
iren.Initialize()
renWin.Render()

vtkRotationMovie(renWin, filename='./test.avi')

iren.Start()

相关问题 更多 >