Blender 使用 python 脚本创建屏幕截图,但在后台 运行 时不创建
Blender creates screenshot using python script but not when running in background
我疯了还是这个功能有一些错误(在后台使用 python 脚本和 blender 运行)?
1/ 将以下代码(来自 screenshot.py)复制/粘贴到 Blender 中(切换到脚本视图),它会截取屏幕截图,但是...
2/ 从命令行调用此脚本:(这样您就可以在使用脚本修改场景时自动截取屏幕截图...用于您的博客、教程等)
blender --background --python screenshot.py
如果不提供上下文中 "incorrect" 的信息,它将崩溃
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”参数,它会生成一个空的屏幕截图(你的 window 的大小,全是灰色)。与此同时,取消注释
#bpy.context.window.screen = bpy.data.screens['3D View Full']
and/or
#space.viewport_shade = 'RENDERED'
并且您会看到您的 Blender 界面受到影响(默认情况下,您的视图布局从 'Default' 切换到“3D 全视图”and/or 您的视口阴影从 'Solid' , to 'Rendered') ...所以脚本实际上被解释但它不生成屏幕截图!
无论如何,问题似乎来自直接从命令行使用“--python somescript.py”调用 Blender
我可能漏掉了什么?!感谢您的帮助
从一个 Blender 人那里得到了答案(感谢谢尔盖)。底线:这是一个限制,因为所有通过命令行参数传递的脚本都是在命令行处理时执行的,在任何 OpenGL 绘制完成之前 !
The warning is caused by script trying to trick the system and
override the context, that context is likely in inconsistent state.
When running screenshot from the interface you don't need to override
any of the contexts.
All the scripts passed via command line argument are executed at
command line processing time, prior to any OpenGL draw is done. The
screenshot operator itself is just reading OpenGL buffer,m without
doing any actual drawing (it can't draw anything since that'd be
unsafe).
When running blender in background mode, there is no window created,
which also means there is no OpenGL context. You can;t use screenshot
in such configuration.
So thanks for the report, but it's just limitation which can not be
easily bypassed.
Precision :(因为提供的代码没有显示尝试 "trick" Blender 的所有尝试)
遗憾的是,如果您也/仍然对此类功能感兴趣,则必须跳出(Blender)框思考!不要浪费时间尝试 "trick" Blender,例如延迟脚本执行、使用应用程序处理程序、在文本编辑器中伪造脚本导入等...我已经为您完成了:它不会工作,可能出于非常相似的原因。
我疯了还是这个功能有一些错误(在后台使用 python 脚本和 blender 运行)?
1/ 将以下代码(来自 screenshot.py)复制/粘贴到 Blender 中(切换到脚本视图),它会截取屏幕截图,但是...
2/ 从命令行调用此脚本:(这样您就可以在使用脚本修改场景时自动截取屏幕截图...用于您的博客、教程等)
blender --background --python screenshot.py
如果不提供上下文中 "incorrect" 的信息,它将崩溃
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”参数,它会生成一个空的屏幕截图(你的 window 的大小,全是灰色)。与此同时,取消注释
#bpy.context.window.screen = bpy.data.screens['3D View Full']
and/or
#space.viewport_shade = 'RENDERED'
并且您会看到您的 Blender 界面受到影响(默认情况下,您的视图布局从 'Default' 切换到“3D 全视图”and/or 您的视口阴影从 'Solid' , to 'Rendered') ...所以脚本实际上被解释但它不生成屏幕截图!
无论如何,问题似乎来自直接从命令行使用“--python somescript.py”调用 Blender
我可能漏掉了什么?!感谢您的帮助
从一个 Blender 人那里得到了答案(感谢谢尔盖)。底线:这是一个限制,因为所有通过命令行参数传递的脚本都是在命令行处理时执行的,在任何 OpenGL 绘制完成之前 !
The warning is caused by script trying to trick the system and override the context, that context is likely in inconsistent state. When running screenshot from the interface you don't need to override any of the contexts.
All the scripts passed via command line argument are executed at command line processing time, prior to any OpenGL draw is done. The screenshot operator itself is just reading OpenGL buffer,m without doing any actual drawing (it can't draw anything since that'd be unsafe).
When running blender in background mode, there is no window created, which also means there is no OpenGL context. You can;t use screenshot in such configuration.
So thanks for the report, but it's just limitation which can not be easily bypassed.
Precision :(因为提供的代码没有显示尝试 "trick" Blender 的所有尝试)
遗憾的是,如果您也/仍然对此类功能感兴趣,则必须跳出(Blender)框思考!不要浪费时间尝试 "trick" Blender,例如延迟脚本执行、使用应用程序处理程序、在文本编辑器中伪造脚本导入等...我已经为您完成了:它不会工作,可能出于非常相似的原因。