【发布时间】:2017-12-09 18:34:04
【问题描述】:
我是疯了还是这个功能有一些错误(使用 python 脚本和后台运行的搅拌机)?
1/ 在 Blender 中复制/粘贴以下代码(来自 screenshot.py)(切换到脚本视图),它会截取屏幕截图,但是...
2/ 从命令行调用此脚本:(这样您就可以在使用脚本修改场景时自动进行屏幕截图...用于您的博客、教程等)
blender --background --python screenshot.py
而且它会崩溃而不给出上下文中“不正确”的信息
screenshot.py:
import os, sys
#FIXME: Blender creates screenshot using python but not when running in background
#
# Same result from Ubuntu stock version (2.76) and from ppa (2.78)
#
# Within Blender : unable to fix this last warning but screenshot is generated !
#
#Traceback (most recent call last):
# File "/usr/share/blender/2.78/scripts/startup/bl_ui/space_text.py", line 32, in draw
# text = st.text
#AttributeError: 'SpaceView3D' object has no attribute 'text'
#
# From command line (crash) : blender --background --python screenshot.py
# Unable to determine what's wrong in the context
#
#Traceback (most recent call last):
#(...)
#File "/usr/share/blender/2.78/scripts/modules/bpy/ops.py", line 187, in __call__
# ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
#RuntimeError: Operator bpy.ops.screen.screenshot.poll() failed, context is incorrect
def screenshot(P_filename, P_path = None):
import bpy
L_saveAs = P_filename
L_saveAs = os.path.join(P_path, L_saveAs) if P_path else os.path.join("/tmp", L_saveAs)
print("Scene saved in " + L_saveAs)
#XXX: switching to 3D full view = maximize scene in main window
#bpy.context.window.screen = bpy.data.screens['3D View Full']
for window in bpy.context.window_manager.windows:
screen = window.screen
print("Window : " + str(window.width) + "x" + str(window.height) + ":" + str(window.x) + "," + str(window.y))
print("Screen : " + str(screen.name) + ", Scene : " + str(screen.scene.name))
#for area in bpy.context.screen.areas:
for area in screen.areas:
print("Area : " + str(area.type))
if area.type == 'VIEW_3D':
for space in area.spaces:
print("Space : " + str(space.type))
if space.type == 'VIEW_3D':
#space.viewport_shade = 'RENDERED'
for region in area.regions:
print("Region : " + str(region.type))
if region.type == 'WINDOW':
L_altBpyCtx = { # defining alternative context (allowing modifications without altering real one)
'area' : area # our 3D View (first found)
, 'blend_data': bpy.context.blend_data # just to suppress PyContext warning, doesn't seem to have any effect
#, 'edit_text' : bpy.context.edit_text # just to suppress PyContext warning, doesn't seem to have any effect
, 'region' : None # just to suppress PyContext warning, doesn't seem to have any effect
#, 'scene' : bpy.context.scene
, 'scene' : screen.scene
, 'space' : space
, 'screen' : window.screen
#, 'window' : bpy.context.window # current window, could also copy context
, 'window' : window # current window, could also copy context
}
bpy.ops.screen.screenshot(L_altBpyCtx, filepath = L_saveAs, full = False)
break #XXX: limit to the window of the 3D View
break #XXX: limit to the corresponding space (3D View)
break #XXX: limit to the first 3D View (area)
screenshot("screenshot.png", ".")
3/ 顺便说一下,在没有“--background”参数的情况下调用它,它将生成一个空屏幕截图(窗口大小,全是灰色)。同时,取消注释
#bpy.context.window.screen = bpy.data.screens['3D View Full']
和/或
#space.viewport_shade = 'RENDERED'
您会看到 Blender 界面受到影响(将视图的布局从“默认”切换到“3D 全视图”和/或视口阴影从默认的“实心”切换到“渲染”).. . 所以脚本实际上被解释了,但它不会生成屏幕截图!
无论如何,问题似乎来自直接从命令行使用“--python somescript.py”调用Blender
我可能错过了什么?!感谢您的帮助
【问题讨论】:
-
--background 选项在没有 UI 的情况下运行...那么您希望如何遍历 UI 元素来截取屏幕截图?
-
Blender process 在后台启动,UI 只是 未显示,但它仍然可用(故意,因此可以编写任务/渲染脚本/自动化)。 UI 组件,即使没有显示,也只是像其他组件一样被视为对象,因此您可以使用/修改/创建它们或使用 bpy.ops.someObject.doSomething 等运算符操作它们。尝试
blender --background --python screenshot.py,您将看到脚本遍历 UI 树的每个组件(窗口 > 屏幕 > 场景 > 区域)。顺便说一句,试试blender --python screenshot.py,你会得到一个“空”的截图。 -
为了更好地理解/完整解释:Blender Official tips and tricks此功能对于有兴趣控制(感谢多视图/逐步屏幕截图)编程建模/操作(使用开源软件:Blender 而不是其他有限的工具,如 OpenScad),让我们在 3D 打印环境中说。能够以编程方式截取屏幕截图而不是只看到最终结果,真的有助于“调试”!
-
来自提示和技巧页面:“非交互式脚本最终可以更有效地不使用 Blenders 界面,而是在命令行上执行脚本。”关键词是“非交互式”——你可以渲染到一个文件中,但你不能对不在屏幕上的东西进行 screen 的拍摄。 UI 根本不呈现。 Blender 对象 和场景图可用,但 UI 元素不可用。为了使您的屏幕截图正常工作,您需要将 UI 呈现到一个文件中,我不知道有任何 UI 以这种方式工作。
-
感谢 Dale 的帮助,但调用相同的命令行(第 3 点)不带“--background”,因此您现在有一个“完整”的 Blender UI 正在运行并且仍然屏幕截图没有达到预期的效果! (如果您取消注释前面指出的行,您可以看到脚本本身修改的界面)。您甚至可以在 bpy.ops.screen.screenshot 中设置 Full = True (因此 all 应该捕获 UI)......结果相同!我实际上可以在后台使用搅拌机从 python 渲染很多东西,但是这种方法是有限的,因为您必须逐个视图渲染视图并且看不到选择
标签: python screenshot blender