Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从Nuke'中提取矢量图像或高分辨率图像;s节点图_Python_Nuke - Fatal编程技术网

Python 从Nuke'中提取矢量图像或高分辨率图像;s节点图

Python 从Nuke'中提取矢量图像或高分辨率图像;s节点图,python,nuke,Python,Nuke,我是一名VFX教师,目前,当我想要抓取节点图的图像用于课堂幻灯片时,我必须使节点图全屏并进行屏幕捕获,但正如您可以想象的那样,对于较大的脚本,我必须缩小到有时无法识别的程度 在我看来,当你放大和缩小时,Nuke的节点图会调整大小,这可能是引擎盖下的某种向量图像。我正在寻找一种方法,要么导出此图像,这样我就可以获得整个节点图的更高分辨率版本。要么作为矢量,要么只是更高分辨率的光栅化图像 有人知道有没有一种方法可以用Python实现这一点吗?或者有一些外部脚本可以做到这一点吗?我一直想要这个,但你的

我是一名VFX教师,目前,当我想要抓取节点图的图像用于课堂幻灯片时,我必须使节点图全屏并进行屏幕捕获,但正如您可以想象的那样,对于较大的脚本,我必须缩小到有时无法识别的程度

在我看来,当你放大和缩小时,Nuke的节点图会调整大小,这可能是引擎盖下的某种向量图像。我正在寻找一种方法,要么导出此图像,这样我就可以获得整个节点图的更高分辨率版本。要么作为矢量,要么只是更高分辨率的光栅化图像


有人知道有没有一种方法可以用Python实现这一点吗?或者有一些外部脚本可以做到这一点吗?

我一直想要这个,但你的问题让我更深入地研究了一下

我不相信有一个真正的矢量图像可用的引擎盖下(它是openGL引擎盖下),但我也不明白为什么没有一种方法来自动化一个完整的分辨率屏幕截图

我已经写了一个脚本,将检查您的节点图的大小,设置缩放到100%,并截图DAG的每一块,然后自动缝合它。这需要几秒钟,因为如果我试图做得太快,事情会因为线程而变得混乱,所以我不得不在每个屏幕截图之间引入人工暂停

您应该能够运行下面的代码。别忘了在倒数第二行设置路径

from PySide2 import QtWidgets, QtOpenGL, QtGui
from math import ceil
import time

 
def get_dag():
    stack = QtWidgets.QApplication.topLevelWidgets()
    while stack:
        widget = stack.pop()
        if widget.objectName() == 'DAG.1':
            for c in widget.children():
                if isinstance(c, QtOpenGL.QGLWidget):
                    return c
        stack.extend(c for c in widget.children() if c.isWidgetType())

def grab_dag(dag, path):
    dag.updateGL()  # This does some funky back and forth but function grabs the wrong thing without it
    pix = dag.grabFrameBuffer()
    pix.save(path)
    
class DagCapture(threading.Thread):
    def __init__(self, path, margins=20, ignore_right=200):
        self.path = path
        threading.Thread.__init__(self)
        self.margins = margins
        self.ignore_right = ignore_right

    def run(self):
        # Store the current dag size and zoom
        original_zoom = nuke.zoom()
        original_center = nuke.center()
        # Calculate the total size of the DAG
        min_x = min([node.xpos() for node in nuke.allNodes()]) - self.margins
        min_y = min([node.ypos() for node in nuke.allNodes()]) - self.margins
        max_x = max([node.xpos() + node.screenWidth() for node in nuke.allNodes()]) + self.margins
        max_y = max([node.ypos() + node.screenHeight() for node in nuke.allNodes()]) + self.margins

        # Get the Dag Widget
        dag = get_dag()
        if not dag:
            raise RuntimeError("Couldn't get DAG widget")

        # Check the size of the current widget, excluding the right side (because of minimap)
        capture_width = dag.width() - self.ignore_right
        capture_height = dag.height()

        # Calculate the number of tiles required to coveral all
        image_width = max_x - min_x
        image_height = max_y - min_y
        horizontal_tiles = int(ceil(image_width / float(capture_width)))
        vertical_tiles = int(ceil(image_height / float(capture_height)))
        # Create a pixmap to store the results
        pixmap = QtGui.QPixmap(image_width, image_height)
        painter = QtGui.QPainter(pixmap)
        painter.setCompositionMode(painter.CompositionMode_SourceOver)
        # Move the dag so that the top left corner is in the top left corner, screenshot, paste in the pixmap, repeat
        for xtile in range(horizontal_tiles):
            left = min_x + capture_width * xtile
            for ytile in range(vertical_tiles):
                top = min_y + capture_height * ytile
                nuke.executeInMainThread(nuke.zoom, (1, (left + (capture_width + self.ignore_right) / 2, top + capture_height / 2)))
                time.sleep(.5)
                nuke.executeInMainThread(grab_dag, (dag, self.path))
                time.sleep(.5)
                screengrab = QtGui.QImage(self.path)
                painter.drawImage(capture_width * xtile, capture_height * ytile, screengrab)
        painter.end()
        pixmap.save(self.path)
        nuke.executeInMainThread(nuke.zoom, (original_zoom, original_center))
        print "Capture Complete"

t = DagCapture("C:\\Users\\erwan\\Downloads\\test.png")
t.start()
我相信这是可以改进的,但希望它能为您节省时间


编辑:我现在对这段代码做了一些改进:

哇,这看起来棒极了。我现在只是在测试。我没有得到任何错误,它通过打印“捕获完成”,但我也没有得到一个文件输出。我更改了将DagCapture类调用到本地下载目录的路径,但没有生成任何内容。我是否需要安装其他库,或者是您正在使用的Nuke标准库(12.1v2)?您好。我注意到,我没有进行任何形式的检查,以查看保存到磁盘是否成功。我走错了路,一切都表现得好像成功了一样,但什么也没发生。我现在没有时间更改它,但是在pix.save()前面添加一个打印,看看它是打印False还是True,它返回False。。。。更正后,它返回x4 FalsSright,这意味着它无法保存。仔细检查路径,如果在windows上确保放置了双反斜杠而不是单反斜杠,请确保目录存在(这不会创建目录),我编辑了答案,添加了一个指向GitHub的链接,在这里我改进了我最初为您编写的代码,添加了一个UI,并允许自定义缩放级别、边距等。。。