繁体   English   中英

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

如果不提供有关上下文中“不正确”的信息,它将崩溃

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

我可能丢失了什么? 谢谢你的帮助

得到了一个搅拌机家伙的答案(感谢谢尔盖)。 底线: 由于所有通过命令行参数传递的脚本都是在命令行处理时执行的,因此在进行任何OpenGL绘制之前都是有限制的

该警告是由于脚本试图欺骗系统并覆盖上下文而引起的,该上下文可能处于不一致状态。 从界面运行屏幕截图时,您无需覆盖任何上下文。

在完成任何OpenGL绘制之前,所有通过命令行参数传递的脚本均在命令行处理时执行。 屏幕截图操作符本身只是在读取OpenGL缓冲区,而没有进行任何实际绘制(它不能绘制任何东西,因为那样会很不安全)。

在后台模式下运行Blender时,没有创建任何窗口,这也意味着没有OpenGL上下文。 您不能在这种配置中使用屏幕截图。

因此,感谢您的报告,但这只是限制,不能轻易绕开。

精度 :(由于提供的代码未显示尝试“欺骗” Blender的所有尝试)

可悲的是,如果您也/仍然对这种功能感兴趣,则必须在(Blender)框外思考! 不要浪费时间尝试“欺骗” Blender,例如延迟脚本执行,使用应用程序处理程序,在文本编辑器中伪造脚本导入等。...我已经为您做到了:它不起作用,可能是出于非常相似的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM