Blender使用python脚本创建屏幕截图,但在后台运行时不创建

Blender使用python脚本创建屏幕截图,但在后台运行时不创建,python,screenshot,blender,Python,Screenshot,Blender,我疯了吗,或者这个特性(使用python脚本在后台运行blender)有什么缺陷 1/在Blender(切换到脚本视图)中复制/粘贴以下代码(来自screenshot.py),它将获得一个屏幕截图,但 2/从命令行调用此脚本:(这样,当您使用脚本修改场景时,您可以自动进行屏幕截图…用于您的博客、教程等) 它将崩溃,而不提供上下文中“不正确”的信息 screenshot.py: import os, sys #FIXME: Blender creates screenshot using pyt

我疯了吗,或者这个特性(使用python脚本在后台运行blender)有什么缺陷

1/在Blender(切换到脚本视图)中复制/粘贴以下代码(来自screenshot.py),它将获得一个屏幕截图,但

2/从命令行调用此脚本:(这样,当您使用脚本修改场景时,您可以自动进行屏幕截图…用于您的博客、教程等)

它将崩溃,而不提供上下文中“不正确”的信息

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'
您将看到您的混合器界面受到影响(将视图布局从“默认”切换到“三维全视图”和/或将视口着色从“实体”(默认情况下)切换到“渲染”)。。。因此,脚本实际上是解释的,但它不会生成屏幕截图

不管怎样,问题似乎来自于直接从命令行使用“-pythonsomescript.py”调用Blender


我可能错过了什么?!谢谢你的帮助

我从一个果汁商那里得到了答案(谢谢谢尔盖)。底线:这是一个限制,因为通过命令行参数传递的所有脚本都是在命令行处理时执行的,在任何OpenGL绘图完成之前执行的

该警告是由于脚本试图欺骗系统和 重写上下文,则该上下文可能处于不一致状态。 从界面运行屏幕截图时,不需要覆盖 任何上下文

通过命令行参数传递的所有脚本都在 命令行处理时间,在任何OpenGL绘图完成之前。这个 屏幕截图操作符本身只是读取OpenGL缓冲区,m而不是 做任何实际的绘图(它不能画任何东西,因为那是 不安全)

在后台模式下运行blender时,不会创建任何窗口, 这也意味着没有OpenGL上下文。你可以;不要使用截图 在这种配置中

所以,谢谢你的报告,但这只是限制,不能 容易绕过

精度:(因为提供的代码没有显示试图“欺骗”搅拌机的所有尝试)


可悲的是,如果你也/仍然对这样的功能感兴趣,你将不得不跳出(搅拌机)的框框去思考!不要浪费时间尝试“欺骗”混合器,比如延迟脚本执行、玩应用程序处理程序、在文本编辑器中假装脚本导入等等。。。我为您做了:它不起作用,可能是因为一个非常相似的原因。

后台选项在没有UI的情况下运行…那么您希望如何迭代UI元素以获取屏幕截图?Blender进程在后台启动,UI只是没有显示,但仍然可用(出于目的,因此可以编写脚本/自动执行任务/渲染).UI组件,即使没有显示,也只是像其他组件一样被视为对象,因此您可以使用/修改/创建它们,或者使用诸如bpy.ops.someObject.doSomething之类的操作符对它们进行操作。尝试
blender--background--python screenshot.py
,您将看到脚本在UI树的每个组件中迭代(窗口>屏幕>场景>区域)。顺便说一句,试试
blender--python screenshot.py
,你会得到一个“空”屏幕截图。为了更好地理解/完整解释:这个功能对于那些对控制(多亏了多视图/分步屏幕截图)编程建模/操作感兴趣的人来说非常有用(使用开源软件:Blender,而不是其他有限的工具,如OpenScad),比如说在3D打印环境中。与其只看到最终结果,不如通过编程方式拍摄屏幕截图,这真的有助于“调试”!从提示和技巧页面:“非交互式脚本根本不使用Blenders界面,而是在命令行上执行脚本,这样会更有效。”关键字是“非交互式”"-您可以渲染到文件,但不能对屏幕上没有的内容进行屏幕截图。UI根本没有渲染。混合器对象和场景图可用,但UI元素不可用。为了使屏幕截图正常工作,您需要将UI渲染到文件,我不知道有哪种UI可以这样工作。感谢Dale提供的帮助,但调用相同的命令行(第3点)时没有“--background”,因此您现在有一个“完整”的Blender UI正在运行,但屏幕截图仍然没有达到预期效果!(如果您取消注释前面指示的行,您可以看到脚本本身修改的界面)。您甚至可以在bpy.ops.screen.screenshot中设置Full=True(因此所有UI都应该被捕获)…结果相同!实际上,我可以在后台使用blender从python渲染很多东西,但这种方法是有限的,因为您必须逐个视图渲染,并且无法查看选择blender 2.8中是否仍然存在此问题?
#space.viewport_shade = 'RENDERED'