Skip to content
Snippets Groups Projects
exr_sequence_to_jpeg.py 2.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • # This file is supposed to run inside Blender:
    
    # blender thefile.blend \
    #     --python /path/to/exr_sequence_to_jpeg.py \
    #     -- --exr-pattern /path/to/exr/files/prefix-*.exr
    
    
    import argparse
    import pathlib
    
    import sys
    
    import bpy
    
    # Find the EXR files to process.
    dashdash_index = sys.argv.index('--')
    parser = argparse.ArgumentParser()
    
    parser.add_argument('--exr-glob')
    
    parser.add_argument('--output-pattern')
    cli_args, _ = parser.parse_known_args(sys.argv[dashdash_index + 1:])
    
    
    exr_glob = pathlib.Path(cli_args.exr_glob)
    imgdir = exr_glob.parent
    exr_files = sorted(imgdir.glob(exr_glob.name))
    
    
    if not exr_files:
    
        raise ValueError(f'No files found for pattern {exr_glob}')
    
    
    # Create a copy of the scene without data, so we can fill the sequence editor
    # with an image sequence.
    bpy.ops.scene.new(type='EMPTY')
    
    scene = bpy.context.scene
    se = scene.sequence_editor_create()
    
    # Place files at the correct frame, based on their filename.
    # This makes the rendering consistent w.r.t. gaps in the frames.
    # This assumes the files are named '000020.exr' etc.
    min_frame = float('inf')
    max_frame = float('-inf')
    
    
    # Interpret the last continuous string of digits as frame number.
    frame_nr_re = re.compile(r'[0-9]+$')
    print(f'Loading {len(exr_files)} EXR files:')
    
    for file in exr_files:
    
        match = frame_nr_re.search(file.stem)
        if not match:
            raise ValueError(f'Unable to find frame number in filename {file.name}')
        frame_num = int(match.group(), 10)
    
        min_frame = min(min_frame, frame_num)
        max_frame = max(max_frame, frame_num)
    
        print(f'   - {file} -> frame {frame_num}')
    
        se.sequences.new_image(file.name, str(file), 1, frame_num)
    
    print(f'Found files for frame range {min_frame}-{max_frame}')
    print()
    sys.stdout.flush()
    
    
    scene.frame_start = min_frame
    scene.frame_end = max_frame
    
    render = scene.render
    render.use_sequencer = True
    render.filepath = str(imgdir / cli_args.output_pattern)
    render.image_settings.file_format = 'JPEG'
    render.image_settings.quality = 90
    render.use_overwrite = True  # overwrite lesser quality previews
    
    bpy.ops.render.render(animation=True, use_viewport=False)
    bpy.ops.wm.quit_blender()