2
$\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$
  • $\begingroup$ Simply pass files=self.files, directory=self.directory straight to the operator. $\endgroup$ – batFINGER Oct 12 '15 at 14:26
  • $\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$ – user2739158 Oct 12 '15 at 14:28
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$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.