3
$\begingroup$

The main goal is to load a sequence into the VSE and read the metadata of each image. Reading the metadata works fine but the fileselect_add returns me only one file. Please help me to add a sequence into the VSE.

The ExportSomeData is copy&paste from another example.

My first attempt...

import bpy
import os
import exifread

# open image file for test
f = open('/mydir/myfile.tif', 'rb')
tags = exifread.process_file(f)
print("ISO: %s" % tags['EXIF ISOSpeedRatings'])
print("Brightness: %s" % tags['EXIF BrightnessValue'])

class ExportSomeData(bpy.types.Operator):
    bl_idname = "export.some_data"
    bl_label = "Export Some Data"

    filepath = bpy.props.StringProperty(subtype="FILE_PATH")

    @classmethod
    def poll(cls, context):
        return context.object is not None

    def execute(self, context):
        print(self.filepath)
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}

# register
bpy.utils.register_class(ExportSomeData)

# test
bpy.ops.export.some_data('INVOKE_DEFAULT')

Update 2

@batFINGER thx

I'm updated my script with the example from: http://blenderartists.org/forum/showthread.php?164765-Scripting-examples-for-2-5-update-Mar-26th-2010&p=1975106&viewfull=1#post1975106

But the script generate an error:

Traceback (most recent call last):
File "...blendfile.blend/Text", line 95, in execute
File ".../blender-2.76-rc1-linux-glibc211-x86_64/2.76/scripts/modules/bpy/ops.py", line 189, in __call__
ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.sequencer.image_strip_add.poll() failed, context is incorrect

The updated script:

class OBJECT_OT_custompath(bpy.types.Operator):
    bl_idname = "object.custom_path"
    bl_label = "Select image files"
    __doc__ = ""


    filename_ext = ".tif"
    filter_glob = bpy.props.StringProperty(default="*.tif;*.png;*.jpeg;*.jpg", options={'HIDDEN'})    


    #this can be look into the one of the export or import python file.
    #need to set a path so so we can get the file name and path
    filepath = bpy.props.StringProperty(name="File Path", description="Filepath used for importing txt files", maxlen= 1024, default= "")
    files = bpy.props.CollectionProperty(
        name="File Path",
        type=bpy.types.OperatorFileListElement,
        )    

    def execute(self, context):
        #set the string path fo the file here.
        #this is a variable created from the top to start it
        #bpy.context.scene.MyString = self.properties.filepath

        files = []

        print("*************SELECTED FILES ***********")
        for file in self.files:
            files.append(file.name)
            print("FILENAME: %s" % file.name)

        files = [{"name":i} for i in files]

        directory = os.path.dirname(self.filepath) + "/"
        print("FILEPATH: %s" % directory)


        bpy.ops.sequencer.image_strip_add(
            directory = directory,
            channel = 1,
            files = files,
            frame_start=1,
            frame_end=20,
            filemode = 9,
            filter_image = True,
            display_type = 'FILE_DEFAULTDISPLAY')

        return {'FINISHED'}


    def draw(self, context):
        self.layout.operator('file.select_all_toggle')        
    def invoke(self, context, event):
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}

bpy.utils.register_class(OBJECT_OT_custompath)
bpy.ops.object.custom_path('INVOKE_DEFAULT')

Update 3

The wrong context generates the error. Last night ... i found this snippet to construct the context...

    scene = bpy.data.scenes["Scene"]    
    screen = bpy.data.screens['Video Editing']      
    for area in screen.areas:
        if area.type == 'SEQUENCE_EDITOR':
            break

    context = {
        'window': bpy.context.window,
        'scene': scene,
        'screen': screen,
        'area': area,
    }

    bpy.ops.sequencer.image_strip_add(context,
        relative_path = False,
        directory = directory,
        .
        .
        .

Update 4

Now i catch the current screen and scene...

    for file in self.files:
        files.append(file.name)

    screen = bpy.context.window.screen
    for area in screen.areas:
        if area.type == 'SEQUENCE_EDITOR':
            break

    files = [{"name":i} for i in files]

    context = {
        'window': bpy.context.window,
        'scene': bpy.context.scene,
        'screen': screen,
        'area': area,
    }

    bpy.ops.sequencer.image_strip_add(context,
        relative_path = False,
        directory = directory,
        files = files,
        frame_start=1,
        frame_end=20,
        filemode = 9,
        filter_image = True,
        display_type = 'FILE_DEFAULTDISPLAY')

    strip = bpy.context.scene.sequence_editor.active_strip

@batFINGER - your solution with

path = os.path.join(self.directory, files[0].name) # need the lowest index
strip = se.sequences.new_image("strip_name", path, channel, 1)
for f in self.files:
    strip.elements.append(f.name)

doesn't work for me. The image strip contains only the first image and the strips in the first channel will thrown over each other.

$\endgroup$
1
  • $\begingroup$ files = self.files generates an error TypeError: Converting py args to operator properties: SEQUENCER_OT_image_strip_add.files expected a each sequence member to be a dict for an RNA collection, not OperatorFileListElement $\endgroup$ Oct 12, 2015 at 14:28

1 Answer 1

2
$\begingroup$

Use the files collection

class OBJECT_OT_custompath(bpy.types.Operator):
    bl_idname = "object.custom_path"
    bl_label = "Select txt files"
    __doc__ = ""


    filename_ext = ".txt"
    filter_glob = StringProperty(default="*.txt", options={'HIDDEN'})    


    #this can be look into the one of the export or import python file.
    #need to set a path so so we can get the file name and path
    filepath = StringProperty(name="File Path", description="Filepath used for importing txt files", maxlen= 1024, default= "")
    files = CollectionProperty(
        name="File Path",
        type=bpy.types.OperatorFileListElement,
        )    
    def execute(self, context):
        #set the string path fo the file here.
        #this is a variable created from the top to start it
        bpy.context.scene.MyString = self.properties.filepath


        print("*************SELECTED FILES ***********")
        for file in self.files:
            print(file.name)

        print("FILEPATH %s"%self.properties.filepath)#display the file name and current path        
        return {'FINISHED'}


    def draw(self, context):
        self.layout.operator('file.select_all_toggle')        
    def invoke(self, context, event):
        wm = context.window_manager
        wm.fileselect_add(self)
        return {'RUNNING_MODAL'}

snippet from http://blenderartists.org/forum/showthread.php?164765-Scripting-examples-for-2-5-update-Mar-26th-2010&p=1975106&viewfull=1#post1975106

EDIT

To add a new image strip for each

#make sure the scene has a sequencer
scene.sequence_editor_create()
se = scene.sequence_editor
for channel, f in enumerate(self.files):
    path = os.path.join(self.directory, f.name)
    strip = se.sequences.new_image("strip_name", path, channel, 1)
    strip.frame_still_end = 20

to add all to one image strip

path = os.path.join(self.directory, files[0].name) # need the lowest index
strip = se.sequences.new_image("strip_name", path, channel, 1)
for f in self.files:
    strip.elements.append(f.name)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .