@raf.k: Beim Geschwindigkeitsverhältnis kommt darauf an was Du machen möchtest. Für solche "number crunching"-Aufgaben ist reines Python natürlich um einiges langsamer als zum Beispiel C. Andererseits gibt es `numpy` mit dem Du hier eventuell etwas herausholen kannst.
Ansonsten kann man an Deinem Quelltext einiges verbessern. Unnötige Funktionsaufrufe weglassen und "statische" Berechnungen nur einmal durchführen. Ich gehe die Funktion mal gnadenlos durch. Sorry.
Der Name `a` für das dritte Argument ist ziemlich nichtssagend. `hg` ist auch etwas kurz.
Die Ausgabe in der ersten Zeile der Funktion greift auf die Kommandozeile zurück. Das wird also auch ausgegeben, wenn man die Funktion mit ganz anderen Werten aufruft als diese Ausgabe vermuten lässt. Schlimmer noch: Man kann die Funktion gar nicht aufrufen, wenn es keine Kommandozeilenargumente gibt, also zum Beispiel um sie isoliert zu testen.
Zeilen 4 und 5 können wegfallen weil den entsprechenden Namen in der Schleife auf jeden Fall etwas zugewiesen wird.
Bei der ``for``-Schleife stellt sich die Frage wo `xSize` und `ySize` herkommen. Die sollten als Argumente übergeben werden.
`range` erzeugt eine Liste mit den ganzen Zahlen. Die brauchen wir hier aber gar nicht, weshalb `xrange` speicherschonender ist. Ausserdem wird mit `i` innerhalb der Schleife zweimal die gleiche Berechnung durchgeführt. Man kann gleich in der Schleife die richtigen Werte erzeugen lassen und spart damit zwei Multiplikationen und eine Addition pro Durchlauf.
Bei der Berechnung (1) sind zu viele explizite `float()`-Aufrufe. Es reicht eine Fliesskommazahl in der Rechnung um das gewünschte Ergebnis zu bekommen.
Die beidem ``if``-Abfragen lassen sich mit `min()` und `max()` ausdrücken.
`struct.pack()` drei mal mit den gleichen Werten aufrufen, in jedem Schleifendurchgang die 255 erneut als Byte verpacken und das ``+=`` für jedes Byte sind Zeitfresser. ``+=`` bedeutet hier: Nimm die alte Zeichenkette, kopiere sie im Speicher und hänge ein Byte an und gib die alte Zeichenkette wieder frei. Das ist sehr viel unnötiges herumschaufeln von Bytes, bloss um eines anzuhängen. Anstelle von `struct.pack()` kann man hier auch einfach das Gegenstück zur `ord()`-Funktion nehmen: `chr()`.
Das alles berücksichtigt könnte die Funktion so aussehen (ungetestet):
Code: Alles auswählen
def mod_hg_korrektur(bild, hg, x_size, y_size, a):
print 'Ziehe %s von %s ab' % (sys.argv[3], sys.argv[2])
temp_out = list()
for i in xrange(18, 18 + x_size * y_size * 4, 4):
temp_hg = max(1, ord(hg[i]))
temp = min(255, int(float(ord(bild[i])) / temp_hg * a * 255)) # (1)
#temp = ord(bild[i]) * 255 # (2)
temp_out.append(chr(temp) * 3 + '\xff')
return bild[:18] + ''.join(temp_out)
Wobei die Idee von rayo (`array.array`) oder gar `numpy` das ganze sicher auch noch etwas vereinfachen und letzeres bestimmt schneller ist.