Skripterweiterung: RGB Werte einzelner Pixel?

  • Ersteller Ersteller Guest
  • Erstellt am Erstellt am
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Habe mal ein wenig experimentiert. Der interne pixelweise Aufruf eines Formelparsers dauert betrüblicherweise wesentlich länger als das reine Skripting.
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Hallo Joachim,

das wundert mich nun nicht wirklich. Die Skripte werden maschinennah kompiliert und dann ausgeführt. Ich glaube nicht, dass Du da so schnell hin kommst, außer vielleicht mit vorkompilierten Elementen.

Die Krux bei der Geschichte ist im wesentlichen der pixelweise Abruf aus der Bitmap. Die ständige Neuberechnung der Position und Aufruf von Methoden kostet nun mal Zeit. Wenn dann vielleicht noch ständig der Speicher gelockt und freigegeben werden muss, ist der Overhead noch wesentlich größer.

Da auch unter JScript auf VB-Arrays zugegriffen werden kann, wenn auch umständlich, würde ich diesen Weg probieren. Oder wie schon erwähnt über Datei-Dump.

Nur meine laienhafte Meinung...
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Wie wäre es denn, wenn das Parsing nicht im eigentlichen Script erfolgt, sondern in einem völlig getrennten Script, das nur diese Aufgabe hat. Der fertige Maschienencode oder P-Code wird nach Fertigstellung in die Zwischenablage abgelegt. Der Scripter nimmt diesen Code und pflanzt in in eine Funktion, die in dem eigentlichen Scipt verwendet wird.

function maskiertersetzen()
{
156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000 156C 166D 5056 306E C000
}

Beim allerersten Funktionsaufruf wird von Fixfoto dieser neue Scriptbefehl wie jeder andere in die Runtime gelegt und kann ab dann bei jedem weiteren Aufruf wie ein ganz normaler FF_XXX-Befehl angesteuert werden. Wäre das ein Weg?
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Hallo Walter,

würde sicher gehen. Problem ist: Müsste dann immer für 2 Versionen gemacht werden: VBScript und JScript bzw. vorher angegeben werden, was die Ausgabe ergeben soll.

Für VB würde das wohl bedeuten:
Code:
Sub Test
   Dim aArray
   Dim sArrayCode
   Dim y
   Dim x
   Dim lHeight
   Dim R, G, B

   lHeight = FF_GetImageHeight() 

   For y = 0 To lHeight - 1
     sArrayCode = FF_GetBinaryImageLine("aArray", y, 0) 'Liefert: aArray = Array(...,...,...,...,...,...)
     Execute sArrayCode
     For x = 0 To UBound(aArray, 1)
        SplitColor(aArray(x), R, G, B)
     Next
   Next
End Sub
Sub SplitColor(ByVal ColorRef, ByRef R, ByRef G, ByRef B)
   ....
End Sub
FF_GetBinaryImageLine(String VarName, Integer LineNr, Boolean ScriptType [0=VBS, 1=JS])

Die Frage ist nur, ob das für JScript auch geht. Gibt es für JScript einen Execute-Befehl? Ansonsten müsste man einen eigenen Code zusammensetzen und per FF_CallScript ausführen. Den Weg über Sub/Function verankern würde ich umgehen. Könnte zu Fehlern führen.

Wobei ich immer noch der Meinung bin: Über Dateiaustausch geht es am schnellsten. Man kann zwar nicht fso.File.ReadAll verwenden, aber fso.File.Read(Länge) geht immer. Dateilänge muss natürlich vorher ermittelt werden, sonst geht es in die Hose.
Den TextStream kann man dann einfach durchgehen:
Code:
   Dim lOffset
   Dim lLineByteLength
   Dim lLineOffset
   Dim x, y
   Dim R, G, B
   Dim sFile

   Dim oFile
   Dim sLength
   Dim oFileData

   Dim sContent

   lLineByteLength = FF_GetImageWidth() * 3 'Evtl Füllbytes müssen bei manchen Daten ggf. berücksichtigt werden. Hier ohne FüllByte. (z. B. WORD oder DWORD-Ausrichtung)

   lLineOffset = 0

   Set oFileData = mv_fso.GetFile(sFile)
   Set oFile = mv_fso.OpenTextFile(sFile, 1)
   sContent = oFile.Read(oFileData.Size)
   oFile.Close
   Set oFile = Nothing
   Set oFileData = Nothing

   For y = 0 To FF_GetImageHeight() - 1
      lOffset = lLineOffset
      For x = 0 To lLineByteLength -1 Step 3
         R = Asc(Mid(sContent, lOffset, 1))
         G = Asc(Mid(sContent, lOffset + 1, 1))
         B = Asc(Mid(sContent, lOffset + 2, 1))
         lOffset = lOffset + 3
         ....
      Next
      lLineOffset = lLineOffset + lLineByteLength
   Next

Das nur als simples Beispiel ohne Anrecht auf Richtigkeit. Bei PPM müsste man dann noch den Header verarbeiten, der aber simpel ist.

Sollen mehrere Operationen durchgeführt werden, ist zu überlegen, ob man die Werte nicht in einem Array 2. Ordnung unterbringt oder das ganze weiter aufdröselt. Der Speicherbedarf steigt dann entsprechend.

Apropo Speicher. Das Abbild ist im Speicher doppelt so groß wie auf der Platte, da die Skripte mit UniCode arbeiten. Sollte aber meist kein Problem sein. Ggf. kann man Zeilenweise einlesen und dann auch gleich schreiben. Dann bleibt der Speicherbedarf geringer, jedoch steigt dann die Plattenlast.
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Wobei ich immer noch der Meinung bin: Über Dateiaustausch geht es am schnellsten. Man kann zwar nicht fso.File.ReadAll verwenden, aber fso.File.Read(Länge) geht immer. Dateilänge muss natürlich vorher ermittelt werden, sonst geht es in die Hose.

Danke für's Mitdenken Euch beiden.

@Werner
Dateiaustausch wäre angemessen, wenn es nur um den Echtlauf ginge, und um in meinem Beispiel die 45 Sekunden Verarbeitungszeit zu verkürzen. Da ich das aber auch für das 'Standard-Beispiel von Joachim' mit OnTimer-Schleife zur sofortigen Abfrage der Reglerbewegung benutzen möchte, kommt der Weg über die Festplatte nicht infrage. Die 2 Sekunden Wartezeit würden sich dadurch wahrscheinlich eher vergrößern.

@Joachim
Aufgrund Nichtwissen denke ich wahrscheinlich zu simpel. Mein Idee ist einfach nur, in den bestehenden Fixfoto-Programmcode ein Modul zu integrieren, das mit der gleichen Geschwindigkeit arbeitet wie alle anderen FF-Werkzeuge. Und damit es die Geschwindigkeit auch erreicht, wollte ich die Compilierung des Scriptcodes umgehen, und sofort einen lauffähigen Assemblercode/Maschinencode integrieren lassen...

VG, Walter
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Die Geschwindigkeit ist nur bei expliziten Einzelfunktionen (wie z.B. FF_ReplaceMasked()) erreichbar, nicht bei irgendwelchen zur Laufzeit generierten Konstrukten.
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Hallo Joachim,

wie wäre es mit Matrizen?
Bild 1 wird mit Bild 2 verrechnet, wobei verschiedene Operationen mit Werten, die angegeben werden müssen ausgeführt werden. Die Werte (Single oder Double) geben die Stärke an, 0 bedeutet keine Aktion.

Beispiel:
FF_CalcMatrix(Integer StackPosDestination, Integer StackPosSource1, Integer StackPosSource2, Integer StackPosMask, Integer UseMask[0=Aus, 1=FF, 2=Maske von StackPosMask], Integer Transparenz [0-255], Integer Layer[R=1, G=2, B=4, Kombination via OR möglich], Double AktionAddition, Double AktionSubtraktion, Double AktionMultiplikation, Double AktionDivision, Single AktionVektorX, Single AktionVektorY)
Natürlich ausbaubar. So könnte man für die Werte für die Aktionen gleich getrennt für R, G und B angeben.


Auch folgendes wäre möglich, erfordert dann aber von Dir vorher ein Parsen der Werte:
FF_CalcMatrix(BString Parameter)

Parameter:
Beispiel: Param1=Wert1, Param2=Wert2, ActionMul(R)=1.68, ActionMulPic(BG)=0.24, Bounds = 2

  • StackPosDst = [0-x]: Zielposition im Stack, wenn nicht angegeben oder fehlerhaft => 0
  • StackPosSrc1 = [0-x]: Quellbildposition, wenn nicht angegeben oder fehlerhaft => 0
  • StackPosSrc2 = [0-x]: Quellbildposition des 2. Bildes, das mit dem 1. verrechnet werden soll, wenn nicht angegeben oder fehlerhaft => 0
  • StackPosMask = [0-x]: MaskenPosition vom Stack, wenn nicht angegeben => Keine
  • UseMask = [True/False]: Normale Maske wird verwendet
  • Transparency = [0-255]: Transparenz
  • ActionAdd(Layer[R|G|B]) = [Double]: Addiert Wert für angegebene Layer in Bild1
  • ActionSub(Layer[R|G|B]) = [Double]: Subtrahiert Wert für angegebene Layer in Bild1
  • ActionMul(Layer[R|G|B]) = [Double]: Multipliziert Wert für angegebene Layer in Bild1
  • ActionDiv(Layer[R|G|B]) = [Double]: Dividiert Wert für angegebene Layer in Bild1
  • ActionAddPic(Layer[R|G|B]) = [Double]: Addiert Wert von Bild2 zu Bild1 für angegebene Layer, Wert ist Faktor(Wertigkeit) für Pixel von Bild 2
  • ActionSubPic(Layer[R|G|B]) = [Double]: Subtrahiert Wert von Bild2 zu Bild1 für angegebene Layer, Wert ist Faktor für Pixel von Bild 2
  • ActionMulPic(Layer[R|G|B]) = [Double]: Multipliziert Wert von Bild2 zu Bild1 für angegebene Layer, Wert ist Faktor für Pixel von Bild 2
  • ActionDivPic(Layer[R|G|B]) = [Double]: Dividiert Wert von Bild2 zu Bild1 für angegebene Layer, Wert ist Faktor für Pixel von Bild 2
  • Bounds=[0=Max,1=Durchschnitt,2=Logarithmisch]: Behandlung des Ergebnisses nach Aktion(en):
    • Max: Ergebnis wird bei 255 abgeschnitten
    • Durchschnitt: Ergebnis wird durch Anzahl der Aktionen geteilt Aktionen können für die Layer unterschiedlich sein!
    • Logarithmisch: Je höher der Wert gegen Maximum, desto flacher die Ergebniskurve
  • VektorXDouble=[Double]: Ergebniswert wird um x Pixel verschoben in Zielbild eingetragen. Ist der Wert "krum", so wird er anteilig verrechnet. (Langsam)
  • VektorYDouble=[Double]: Ergebniswert wird um y Pixel verschoben in Zielbild eingetragen. Ist der Wert "krum", so wird er anteilig verrechnet. (Langsam)
  • VektorXInt=[Integer]: Ergebniswert wird um x Pixel verschoben in Zielbild eingetragen.
  • VektorYInt=[Integer]: Ergebniswert wird um y Pixel verschoben in Zielbild eingetragen.

Ist jetzt nur ein Beispiel und vom Gedankengang mit der heißen Nadel gestrickt. Wäre aber so ein machtvolles Werkzeug. Für mögliche logische Fehler wäre der Anwender selbst verantwortlich (Z. B. Quell und Zielbild identisch)

Nur so meine Gedanken dazu....
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Die Geschwindigkeit ist nur bei expliziten Einzelfunktionen (wie z.B. FF_ReplaceMasked()) erreichbar, nicht bei irgendwelchen zur Laufzeit generierten Konstrukten.

Danke, das war ein interessanter Meinungsaustausch. Ich freue mich schon auf die Veröffentlichung der nächsten Beta, um den Befehl FF_ReplaceMasked() einzusetzen.

Viele Grüße
Walter
 
AW: Skripterweiterung: RGB Werte einzelner Pixel?

Lösung ist gefunden, mußte leider sehr lange danach suchen!!

1. im Zielbild den maskierten Bereich schwarz färben
2. im Quellbild (aus dem eingefügt wird) die Umgebung des maskierten Bereiches schwarz färben (Maske invers)
3. Ab V3.02 B24 : FF_MixImage...mit mix < 0 (=Füllmethode 'addieren') verrechnen lassen

Funktioniert prächtig, der Befehl FF_ReplaceMasked() ist nun nicht mehr erforderlich.

VG, Walter
 
Zuletzt bearbeitet:
Zurück
Oben