Image Sequenzen neu Nummerieren...

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 14. April 2007, 09:20

Auch wenn es wahrscheinlich keiner von euch jemals brauchen werdet. Hier ein schnell zusammen gehacktes Skript:

EDIT1: Skript aktualisiert: Neu RE

EDIT2: Alten Sourcecode gelöscht, neue siehe unten...
Zuletzt geändert von jens am Dienstag 10. Juli 2007, 15:44, insgesamt 2-mal geändert.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Samstag 14. April 2007, 10:13

Mal abgesehen von fehlenden Kommentaren oder nicht vorhandenen Funktionen, aber so wie es aussieht macht dein Regulärer Ausdruck nicht unbedingt das, was du ertwartest:

Code: Alles auswählen

fn_regex = re.compile(r"([\-0-9]+)")
Der könnte auch locker aus "mein-erster-film-szene-01-001" die "-01-001" matchen.

Ach ja: Und ein Feature das nicht getestet ist, ist auch kein Feature.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 14. April 2007, 10:14

Bin nicht gerade der RE experte. Vorschlag, wie man es besser machen kann?

EDIT: Was mir da einfällt: Auch wenn die RE nicht perfekt ist, es passiert nix. Denn ein int("-01-001") geht nicht und es kommt ein Traceback, bevor es richtig losgeht. ;)

Ich hab auch extra ein copy gemacht und benenne die Dateien nicht um. Somit bleiben die Source-Dateien in jedem Fall erhalten ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Samstag 14. April 2007, 12:10

jens hat geschrieben:Bin nicht gerade der RE experte. Vorschlag, wie man es besser machen kann?
Ich würde den so machen:

Code: Alles auswählen

r"^(.*[^\-0-9])?(\-?[0-9]+)$"
Den kannst du dann einfach auf den Dateinamen (ohne Endung) loslassen, und mit "group(2)" den Index holen.
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 14. April 2007, 16:52

Thx. Ich hab es oben aktualisiert.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Dienstag 10. Juli 2007, 15:43

Mit der RE klappt es nicht immer... Nun mache ich es anderes:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
umbenennen einer Render Image Sequenz

kopiert alle Dateien einer Image Sequenz von SOURCE_PATH nach DEST_PATH und
nummeriert dabei die Dateien neu durch.

Anwendungsfall - negative Zeitleiste
------------------------------------
In 3dsmax ist es z.B. möglich die Zeitleiste in den negativen Bereich zu
erweitern. In diesem Falle haben die einzelnen Dateien allerdings ungünstige
Namen.
z.B.:
    Frame-003.png
    Frame-002.png
    Frame-001.png
    Frame-003.png
    Frame0000.png
    Frame0001.png
    Frame0002.png
Zum einen kann diese Sequenz nicht in einem eingelesen werden (z.B. mit
VirtualDub) und zum anderen würde der negative Bereich umgekehrt eingelesen
werden.

Das Skript macht nun aus der Sequenz folgendes:
    Frame-003.png -> Frame_0000.png
    Frame-002.png -> Frame_0001.png
    Frame-001.png -> Frame_0002.png
    Frame-003.png -> Frame_0003.png
    Frame0000.png -> Frame_0004.png
    Frame0001.png -> Frame_0005.png
    Frame0002.png -> Frame_0006.png


Anwendungsfall - fehlende Frames
--------------------------------
Wenn innerhalb einer Image Sequenz Frames fehlen (oder aber auch nur jedes x'te
Frame absichtlich rausgerechnet hat) kann man ebenfalls die Sequenz nicht mit
VirtualDub eingelesen werden.
In dem Falle, sollte das Skript auch wieder eine korrekte Nummerierung
vornehmen. ACHTUNG: Das ist nicht getestet!


Created by Jens Diemer

license:
    GNU General Public License v3
    http://www.opensource.org/licenses/gpl-license.php
"""

import os, sys, re, shutil, time

__version__ = "v2.0"


def make_file_dict(filelist, basename):
    """
    >>> basename = "base"
    >>> filelist = ["base-2.png", "base-1.png", "base-0.png", "base01.png", ]
    >>> make_file_dict(filelist, basename)
    {0: 'base-0.png', 1: 'base01.png', -1: 'base-1.png', -2: 'base-2.png'}
    """
    pos = len(basename)
    file_dict = {}
    for filename in filelist:
        fn, ext = os.path.splitext(filename)
        fileno = int(fn[pos:])
        file_dict[fileno] = filename

    return file_dict


def file_copy(file_dict, basename, source_path, dest_path):
    start_time = time.time()
    filecount = len(file_dict)
    for no, key in enumerate(sorted(file_dict)):
        filename = file_dict[key]
        fn, ext = os.path.splitext(filename)

        src = os.path.join(source_path, filename)
        new_filename = "%s_%04i%s" % (basename, no, ext)

        print "%s -> %s" % (filename, new_filename)

        dst = os.path.join(dest_path, new_filename)

        current_time = int(time.time())
        elapsed = float(current_time-start_time)        # Vergangene Zeit
        estimated = elapsed / (no+1) * (filecount+1)    # Geschäzte Zeit
        if estimated>60:
            time_info = "%.2f/%.2fmin %.2fmin" % (
                elapsed/60.0, estimated/60.0, (estimated-elapsed)/60.0
            )
        else:
            time_info = "%i/%isec %isec" % (
                elapsed, estimated, estimated-elapsed
            )

        print "copy %s/%s %s left (%s)..." % (
            no+1, filecount, filecount-(no+1), time_info
        ),
        shutil.copy2(src, dst)
        print "OK"
        print

def file_sequenz_copy(source_path, dest_path):
    assert os.path.isdir(source_path)
    assert os.path.isdir(dest_path)

    print "Read filenames...",
    filelist = os.listdir(source_path)
    print "OK"

    print "Analyse baename...",
    # Gemeinsamen Basis Namen finden
    basename = os.path.commonprefix(filelist)
    print "OK:", basename

    print "Generate file dictionary...",
    file_dict = make_file_dict(filelist, basename)
    print "OK"

    print "Create destination path...",
    try:
        destination = os.path.join(dest_path, basename)
        os.mkdir(destination)
    except Exception, e:
        print "mkdir error:", e
    else:
        print "OK"

    print
    print "_"*80
    print "START FILE COPY"
    print

    # Dateien kopieren
    file_copy(file_dict, basename, source_path, destination)


def _test():
    print "_"*80
    print "doctest:"
    import doctest
    doctest.testmod()
    print "-"*80
    print "(END)"

if __name__ == "__main__":
    #~ _test()

    file_sequenz_copy(
        r"W:\3dsmax_rendering\Preview01",
        r"D:\Previews"
    )
Diskussion zu get_basename() hier: http://www.python-forum.de/viewtopic.php?p=72856

EDIT: Code aktualisiert: Nun nutzte ich statt der eigenen get_basename() lieber os.path.commonprefix() :)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten