我正在尝试使用Blender的python API将图像缓冲区另存为.png(但这主要只是一个python问题) 我正在尝试通过创建一个线程来保存图像来加快速度,并且创建线程的函数是从刷新3D屏幕时激活的回调处理程序中调用的,以下是完整代码(有点混乱):
import base64, io, os, bgl, gpu, bpy, threading, time, sys
import numpy as np
from gpu_extras.presets import draw_texture_2d
from PIL import Image
import multiprocessing.pool as mpool
finalPath = bpy.context.scene.render.filepath + "hithere.png"
WIDTH = 1920
HEIGHT = 1080
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
def draw2():
global finalPath
global array
global WIDTH
global HEIGHT
global needsSaving
context = bpy.context
scene = context.scene
view_matrix = scene.camera.matrix_world.inverted()
projection_matrix = scene.camera.calc_matrix_camera(
context.depsgraph, x=WIDTH, y=HEIGHT)
offscreen.draw_view3d(
scene,
context.view_layer,
context.space_data,
context.region,
view_matrix,
projection_matrix)
bgl.glDisable(bgl.GL_DEPTH_TEST)
draw_texture_2d(offscreen.color_texture, (0, -125), WIDTH, HEIGHT)
buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
bgl.glReadBuffer(bgl.GL_BACK)
bgl.glReadPixels(0, -125, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
needle = threading.Thread(target=saveIt,args=[buffer, finalPath, WIDTH, HEIGHT])
needle.daemon = True
needle.start()
#### thread.start_new_thread(saveIt,(buffer, finalPath, WIDTH, HEIGHT))
def coby(scene):
frame = scene.frame_current
folder = scene.render.filepath
myFormat = "png"#scene.render.image_settings.renderformat.lower()
outputPath = os.path.join(folder, "%05d.%s" % (frame, myFormat))
global finalPath
finalPath = outputPath
h = bpy.types.SpaceView3D.draw_handler_add(draw2, (), 'WINDOW', 'POST_PIXEL')
bpy.app.handlers.frame_change_pre.clear()
bpy.app.handlers.frame_change_pre.append(coby)
def saveIt(buffer, path, width, height):
array = np.asarray(buffer, dtype=np.uint8)
myBytes = array.tobytes()
im = Image.frombytes("RGBA",(width, height), myBytes)
rawBytes = io.BytesIO()
im.save(rawBytes, "PNG")
rawBytes.seek(0)
base64Encoded = base64.b64encode(rawBytes.read())
txt = "data:image/png;base64," + base64Encoded.decode()
f = open(finalPath, "wb")
f.write(base64.decodebytes(base64Encoded))
f.close()
它确实起作用,除了当我在Blender中播放时间线(它调用frame_pre回调以及3D视图刷新回调(尽管不确定顺序))时,我的大多数图像都被替换了,除了一些没有,如以下屏幕截图所示: [![在此处输入图片描述] [1]] [1]
我最初拥有所有蓝图图像,然后我在线程中运行脚本,并替换了几乎所有蓝图图像,除了一些蓝图图像仍然保留(似乎以随机间隔)。如果我在创建线程后立即调用.join()或根本不使用该线程,则此方法很好用,但是看来线程是使其运行更快的唯一方法。
我一直在寻找如何将线程与队列和池一起使用(How to use python multiprocessing Pool.map within loop,What happened to thread.start_new_thread in python 3, How can I make a background, non-blocking input loop in python?,Creating Threads in python)
SO:为什么不是所有线程都完成了? [1]:https://i.stack.imgur.com/nJCwH.png .................