I load an image texture (of 3 frames) as a material node. I draw on all (3) frames in texture paint mode.
I want to save all modified images at once, preferably with python. How can I save all images of the image sequence at once?
You can just call bpy.ops.image.save_sequence()
within the Image Editor.
If you would like to call the operator from another area, you can override the context:
Blender 3.2+
import bpy
from bpy import context
for area in context.screen.areas:
if area.type == 'IMAGE_EDITOR':
with context.temp_override(area=area):
bpy.ops.image.save_sequence()
break
Blender 2.8+
import bpy
C = bpy.context
for area in C.screen.areas:
if area.type == 'IMAGE_EDITOR':
override = C.copy()
override['area'] = area
bpy.ops.image.save_sequence(override)
break
Console output:
Info: 3 image(s) will be saved in /tmp/
Info: Saved /tmp/untitled_0003.exr
Info: Saved /tmp/untitled_0002.exr
Info: Saved /tmp/untitled_0001.exr
If there is no Image Editor available, you can also switch the current area to the Image Editor, assign the sequence, call the operator and reset the area to its old type:
import bpy
C = bpy.context
img_seq = bpy.data.images['untitled_0001.exr']
# Store current area
area = C.area
old_type = area.type
# Set the area type and assign the sequence
area.type = 'IMAGE_EDITOR'
area.spaces.active.image = img_seq
# Call the operator and reset the area
bpy.ops.image.save_sequence()
area.type = old_type
Console output:
Info: 3 image(s) will be saved in /tmp/
Info: Saved /tmp/untitled_0003.exr
Info: Saved /tmp/untitled_0002.exr
Info: Saved /tmp/untitled_0001.exr
Operator demo based on the operator_node.py
template that comes with Blender in order to save the image sequence of the selected Image node in the Node Editor:
import bpy
class NodeOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "node.simple_operator"
bl_label = "Simple Node Operator"
@classmethod
def poll(cls, context):
space = context.space_data
return space.type == 'NODE_EDITOR' and \
context.active_node.type=='TEX_IMAGE'
def execute(self, context):
image_sequence = context.active_node.image
if image_sequence.source == 'SEQUENCE':
# Store current area
area = context.area
old_type = area.type
# Set the area type and assign the sequence
area.type = 'IMAGE_EDITOR'
area.spaces.active.image = image_sequence
# Call the operator and reset the area
bpy.ops.image.save_sequence()
area.type = old_type
return {'FINISHED'}
def register():
bpy.utils.register_class(NodeOperator)
def unregister():
bpy.utils.unregister_class(NodeOperator)
if __name__ == "__main__":
register()
layout.operator("image.save_sequence")
(already part of the header menu, Image Editor > Image > Save Sequence) Does this answer your question(s)? @Leander
$\endgroup$
Commented
Sep 5, 2021 at 16:28
frame_set()
and save the result which is quite expensive and slow, I guess. The operator on the other hand just saves the image buffer already in memory: github.com/blender/blender/blob/master/source/blender/editors/… @Leander
$\endgroup$
Commented
Sep 6, 2021 at 8:52