Heim  >  Artikel  >  Web-Frontend  >  Eine Einführung in die Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop

Eine Einführung in die Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop

高洛峰
高洛峰Original
2017-02-20 09:02:073206Durchsuche

Photoshop ist eine herausragende Software im Bereich der digitalen Bildbearbeitung. Gleichzeitig ermöglicht es auch Dritten, seine Funktionen in Form von Plug-Ins zu erweitern. Photoshop-Plugins können derzeit in die folgenden neun Typen unterteilt werden: Automatisierung (Stapelverarbeitung) (erscheint im Untermenü „Auto“), Farbaufnahme, Import, Export (erscheint im Untermenü „Importieren“ und „Exportieren“), Erweiterung, Filter, Dateiformat (erscheint unter „Öffnen“, „Speichern unter“), Parsen (mit Exportfunktion), Auswahl (erscheint im Menü „Auswählen“). Hier nehmen wir als Beispiel den Filter, der den Benutzern am vertrautesten ist.
(1) Einführung in den allgemeinen Teil des Plug-Ins:
Wir werden zum Host, indem wir das Hauptprogramm des Plug-Ins aufrufen. In den meisten Fällen handelt es sich um Photoshop (im Folgenden als PS bezeichnet). Ein Plug-in ist eigentlich eine dynamische Linkbibliothek unter dem Windows-System (nur mit einer anderen Erweiterung). PS verwendet LoadLibray zum Laden von Plug-in-Modulen. Wenn der Benutzer die entsprechende Aktion ausführt, wird eine Reihe von PS-Aufrufen an das Plug-in-Modul ausgelöst. Alle diese Aufrufe rufen denselben Einstiegspunkt auf. Der Einstiegspunkt ist eine solche Funktion, die wie folgt definiert ist: (Da PS mit Windows und Macs kompatibel ist, geben wir hier nur die Definition auf dem Windows-System an)

void ENTRYPOINT (
kurzer Selektor ,
void* PluginParamBlock,
Long* PluginData,
Short* Ergebnis);

Selektor:
Vorgangstypanzeige. Wenn Selektor = 0, hat dies für alle Plug-In-Typen die gleiche Bedeutung, nämlich die Aufforderung, ein Dialogfeld „Info“ anzuzeigen. Andere Werte haben je nach Plug-In-Typ unterschiedliche Bedeutungen.

pluginParamBlock:
Dies ist ein Zeiger auf eine große Struktur, die zur Übertragung von Informationen und Daten zwischen dem Host und dem Plug-in verwendet wird. Es gibt unterschiedliche Strukturen für verschiedene Arten von Plugins.

pluginData:
Ein Zeiger auf den Typ int32. Es handelt sich um einen Wert, den PS über mehrere Aufrufe des Plugins hinweg speichert. Eine seiner Standardverwendungen besteht darin, dass das Plug-in einige globale Datenzeiger zur Speicherung an diesen Parameter übergeben kann:

Ergebnis:
Es muss das Ergebnis jedes Mal festlegen, wenn das Plug-in ausgeführt wird heißt. Die Rückgabe von 0 zeigt an, dass im Plugin-Code kein Fehler aufgetreten ist. Wenn ein Fehler auftritt, gibt dieser Wert einen Fehlercode zurück. In Bezug auf Fehlercodes unterteilt ps die Fehlercodebereiche für verschiedene Plug-In-Typen und definiert einige Werte im SDK vor.

Info-Dialog:
Alle Plugins sollten auf About-Aufrufe reagieren. Plug-Ins können ein benutzerdefiniertes Dialogfeld anzeigen. Um jedoch die Konsistenz zu gewährleisten, sollten die folgenden Konventionen eingehalten werden:
(1) Wird in der horizontalen Mitte des Hauptbildschirms und vertikal auf 1/3 der Höhe angezeigt.
(2) Es ist nicht erforderlich, eine OK-Schaltfläche einzufügen, sondern auf Klicks an einer beliebigen Stelle und die Eingabetaste zu reagieren.

(2) Einführung in das Filter-Plug-in
Die Funktion des Filter-Plug-ins besteht darin, den ausgewählten Bereich des Bildes zu ändern. Das Filterverhalten reicht von der Anpassung von Sättigung und Helligkeit bis hin zum Filtern von Bildern und mehr. Die Erweiterung des Filters unter Windows ist „.8BF“.
Das folgende Bild zeigt die Aufrufsequenz zwischen PS- und Filter-Plug-Ins. Es ist ein Bild in der SDK-Dokumentation. Es gibt ein solches Bild Der Filter. Die Aufrufsequenz des Plug-Ins.
      Eine Einführung in die Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop

Filter können über das Filtermenü aufgerufen werden, das den obersten Ausgangspunkt für Aufrufe darstellt. Nach einmaligem Aufruf fügt Photoshop den letzten Filtervorgang dem Untermenü „Letzter Filter“ des Filtermenüs hinzu. Wenn Sie in Zukunft auf dieses Menü klicken, entspricht dies dem „Letzten Filterbefehl“ im Bild oben. Im Folgenden stellen wir den oben dargestellten Prozess kurz vor. Schauen wir uns zunächst die „Vorlage“ der Einstiegspunktfunktion eines Filters an:

EntryPoint Of Plugin :PlugInMain
// Erstellen eine Definition für exportierte Funktionen
#define DLLExport extern " C" __declspec(dllexport)
#define SPAPI

DLLExport SPAPI 
void PluginMain(const int16 selector,
        
void * filterRecord,
        int32 
* Daten,
        int16 
* Ergebnis)

 
Schalter (Selektor)
 {
  
Fall filterSelectorAbout:
   
// DoAbout();
   break;
  
case filterSelectorParameters:
   DoParameters();
   
break;
  
case filterSelectorPrepare:
   DoPrepare();
   
break;
  
case filterSelectorStart:
   DoStart();
   
break;
  
case filterSelectorContinue:
   DoContinue();
   
break ;
  
case filterSelectorFinish:
   DoFinish();
   
break;
  
Standard:
   
*gResult = filterBadParameters;
   
Pause;
 }
}

Beachten Sie, dass die obige Funktion die wichtigste Funktion unseres Filters ist. Da diese Funktion für PS-Aufrufe bereitgestellt wird, können wir sehen, dass diese Funktion als DLL-Exportfunktion deklariert ist. Aus der Aufrufsequenz ist ersichtlich, dass dieser Mechanismus die Funktion dieser Funktion der Fensterprozedur des Fensters sehr ähnlich macht. Die Fensterprozedur wird zum Verarbeiten von Nachrichten basierend auf der MSG-ID verwendet, und diese Funktion wird hauptsächlich zum Ausführen entsprechender Vorgänge basierend auf dem Selektor verwendet. Daher enthalten sie alle eine Switch-Case-Verzweigungsverarbeitungsstruktur.

filterRecord
Der zweite Parameter, der in der obigen Funktion verwendet wird, ist ein Zeiger auf die AboutRecord-Struktur, wenn sie about aufgerufen wird (d. h. selector=0, wenn sie nicht about aufgerufen wird, ist sie ein Zeiger auf die). Die FilterRecord-Struktur ist eine sehr große und komplexe Struktur. Sie ist der Schlüsselträger für die Kommunikation und Datenübertragung zwischen PS und Filtern und enthält insgesamt mehr als 7 Seiten Das Dokument, das zur Einführung der Bedeutung der Mitglieder dieser Struktur verwendet wird. Die vollständige Definition von FilterRecord befindet sich in der Header-Datei:pifilter.h im SDK. Im Folgenden werde ich einige seiner grundlegendsten und wichtigsten Mitglieder erläutern, sobald sie erwähnt werden.

(3) Einführung in den Anrufprozess.

(3.1) filterSelectorParameters-Aufruf:
Wenn der Filter einige Parameter hat, die vom Benutzer eingestellt werden müssen, dann sollte er die Parameter an einem Ort speichern. Stellen Sie dann die Adresse auf die dritten Parameterdaten ein. PS initialisiert diesen Parameter auf NULL. Ob dieser Aufruf erfolgt, hängt von der Aufrufmethode des Benutzers ab. Wenn ein Filter gerade aufgerufen wurde, wird der Filter im letzten Befehlsmenü des Filters angezeigt. Der Benutzer kann dieses Menü mit denselben Parametern verwenden (es wird kein Dialogfeld angezeigt). Zeit zum Anfordern. Benutzer stellt neue Parameter ein) und ruft erneut auf. Dieser Aufruf erfolgt nicht, wenn der Benutzer ihn mit dem letzten Filterbefehl aufruft. (siehe Bild oben). Daher sollten Parameter jedes Mal überprüft, verifiziert und initialisiert werden, wenn falsche Parameter das Risiko eines Programmabsturzes bergen könnten.
Achtung! : Da die gleichen Parameter für Bilder unterschiedlicher Größe verwendet werden können, sollten die Parameter nicht von der Bildgröße abhängen. Beispielsweise sollte ein Parameter nicht von der Breite oder Höhe des Bildes abhängen. Normalerweise ist es sinnvoller, einen Prozentsatz oder einen Skalierungsfaktor als Parameter zu verwenden.
Ihr Parameterdatenblock sollte also die folgenden Informationen enthalten:
1. Eine Signatur, damit der Filter schnell bestätigen kann, dass es sich um seine Parameterdaten handelt.
2. Eine Versionsnummer, damit das Plug-in frei aktualisiert werden kann, ohne die Signatur zu ändern.
3. Identifizierung der Bytereihenfolge. (Für plattformübergreifende Zwecke) Gibt an, welche Endianness derzeit verwendet wird.

Parameterblock (Parameterdatenblock) und Skriptsystem (Skriptbeschreibungssystem)
Das Skriptsystem wird zum Zwischenspeichern unserer Parameter verwendet und wird in jedem Aufruftyp verwendet . Es wird an das Plugin übergeben, sodass Sie es zum Speichern aller Ihrer Parameter verwenden können. Sobald Ihr Parameterblock validiert ist, sollten Sie die Daten aus den übergebenen Parametern lesen und dann Ihre Parameter aktualisieren. Beispiel:
1. Rufen Sie zunächst ValidateMyParameters auf, um Ihre globalen Parameter zu überprüfen oder zu initialisieren.
2. Rufen Sie dann die ReadScriptingParameters-Methode auf, um die Parameter zu lesen und in Ihre globale Parameterdatenstruktur zu schreiben.

(3.2) filterSelectorPrepare-Aufruf:
Mit diesem Aufruf kann Ihr Plug-in-Modul den Speicherzuweisungsalgorithmus von ps anpassen. Der Befehl „Letzter Filter“ beginnt mit diesem Aufruf. PS setzt maxSpace (das ein Mitglied der FilterRecord-Struktur ist (zweiter Parameter; neue Mitglieder, die danach erscheinen, werden nicht speziell erklärt) auf die maximale Anzahl von Bytes, die er für das Plug-In zuweisen kann.
imageSize-, Planes- und filterRect-Mitglieder:
Diese Mitglieder sind jetzt definiert (bezogen auf SDK 6.0) und können zur Berechnung Ihres Speicherbedarfs verwendet werden. imageSize, Bildgröße. Ebenen, Anzahl der Kanäle.
filterRect: Filterrechteck.
Hier möchte ich noch einmal filterRect hervorheben, den von PS definierten Rect-Typ (ähnlich der RECT-Struktur der Windows-API). Dieses Konzept ist auch das Konzept des „Auswahl umschließenden Rechtecks“, das in meinem Forschungsbeitrag zu „Prinzipien des Verschiebungsfilters“ erwähnt und wiederholt hervorgehoben wurde. Zu diesem Zeitpunkt hatte ich noch keinen Kontakt mit PS SDK. Hier sehen wir, dass es im Photoshop-Code filterRect heißt.
bufferSpace:
            Wenn der Filter mehr als 32 KB Speicherplatz zuweisen möchte, sollte dieses Mitglied auf die Anzahl der Bytes eingestellt werden, die Sie beantragen möchten. ps wird versuchen, vor dem nächsten Aufruf (Anruf starten) einen Speicherplatz dieser Größe freizugeben, um sicherzustellen, dass Ihr nächster Aufruf erfolgreich ist.

(3.3) filterSelectorStart-Aufruf:
In diesem Aufruf sollten Sie den Parameterdatenblock überprüfen, Ihre eigenen Parameter basierend auf den von ps übergebenen Parametern aktualisieren und bei Bedarf Ihre Benutzeroberfläche anzeigen. Dann gehen Sie in Ihren Datenverarbeitungsprozess.
AdvanceState-Rückruf: (wird verwendet, um PS aufzufordern, die entsprechenden Daten zu aktualisieren)
Dies ist eine sehr wichtige Rückruffunktion, die PS für den Filter bereitstellt. Sie ist wie folgt definiert:
#define MACPASCAL
typedef short OSErr;
typedef MACPASCAL OSErr (*AdvanceStateProc) (void);
Seine Funktion besteht darin, PS aufzufordern, die veralteten Daten in FilterRecord sofort zu aktualisieren. Beispielsweise können wir unser neues Verarbeitungsrechteck festlegen und dann diese Funktion aufrufen, und dann können wir nach diesem Aufruf die neuen Daten erhalten, die wir benötigen. Wenn Sie diesen Rückruf verwenden, kann die gesamte Kernverarbeitung im Startaufruf erfolgen, ohne dass ein Fortsetzungsaufruf verwendet werden muss. Wenn die Verarbeitung abgeschlossen ist, können Sie inRect=outRect=maskRect=NULL setzen.
Wenn Sie diesen Rückruf nicht verwenden, sollten Sie den ersten rechteckigen Bereich festlegen und dann die Schleifenverarbeitung mit continue aufrufen.
Beispielsweise können wir die folgende Schleife im Startaufruf verwenden, um das Bild zu verarbeiten, bis die gesamte Bildverarbeitung abgeschlossen ist.

Beispiel für einen AdvanceState-Rückruf
für(..)
{
SetOutRect(out_recc);
gFilterRecord
->outLoPlane=0;
gFilterRecord
->outHiPlane=(g_Planes-1);

 
//Bitte PS um Datenaktualisierung!
 *gResult = gFilterRecord- >advanceState();
 
if (*gResult ! =kNoErr)
 
gehe zufertig;

 
//Daten werden verarbeitet
. . . . .
}


Inrect, Outress & Maskrect
Set inRect und Outress (Maskrect) wird angefordert, um den ersten Verarbeitungsbereich anzufordern. Wenn möglich, sollten Sie das Bild in kleinere Stücke schneiden, um den Speicherbedarf bei der Datenübergabe zu reduzieren. Es ist üblich, 64x64- oder 128x128-Patches zu verwenden.

(3.4) filterSelectorContinue-Aufruf:
Wenn eines von inRect, outRect, maskRect kein leeres Rechteck ist, wird dieser Aufruf weiterhin ausgeführt.
inData, outData & maskData
Diese drei Mitglieder sind leere * Zeiger, die auf den Startpunkt der von Ihnen angeforderten Bilddaten verweisen. Beim Aufrufen besteht unsere Hauptaufgabe darin, die Daten zu berechnen und dann festzulegen wird entsprechend dem von Ihnen angeforderten rechteckigen Bereich mit den Bilddaten gefüllt. Anschließend besteht Ihre Verarbeitungsaufgabe hauptsächlich darin, den outData-Datenbereich zu ändern und PS Ihre Verarbeitungsergebnisse mitzuteilen, und PS aktualisiert die Ergebnisse im Bild. Beachten Sie, dass Sie die übergebene Auswahl und die Auswahlform nicht berücksichtigen müssen, da dieses funktionierende PS automatisch die Daten außerhalb der Auswahl schützt. Sie müssen nur auf Ihren eigenen Algorithmus achten. Nachdem die Verarbeitung abgeschlossen ist, legen Sie inRect und outRect für die nächste Verarbeitung fest. Wenn es vorbei ist, lassen Sie sie einfach leer. Beachten Sie, dass inRect nicht unbedingt dasselbe ist wie outRect.
progressProc-Rückruf: (wird zum Festlegen des PS-Fortschrittsbalkens verwendet)
Sein Typ ist definiert als:
typedef MACPASCAL void (*ProgressProc) (int32 done, int32 total);

Dies ist die von PS bereitgestellte Rückruffunktion zum Festlegen des Fortschrittsbalkens. Das Plug-in kann diesen Rückruf verwenden, um PS den Fortschrittsbalken unten aktualisieren zu lassen. Einer ist die Anzahl der abgeschlossenen Aufgaben und der andere ist die Gesamtzahl Anzahl der Aufgaben. Wenn Sie Benutzern Feedback zu Ihrem Verarbeitungsfortschritt geben müssen, können Sie den Fortschritt wie folgt festlegen:
gFilterRecord->progressProc ( progress_complete, progress_total );
abortProc callback: (wird zum Melden verwendet to Der Host fragt ab, ob der Benutzer eine Abbruchaktion durchgeführt hat)
Der Typ ist definiert als:
typedef Boolean (*TestAbortProc) (void);
Dieser Rückruf wird verwendet, um abzufragen, ob der Benutzer die abgebrochen hat Vorgang, der lange dauert Während der Verarbeitung sollte das Plug-in diese Funktion mehrmals pro Sekunde aufrufen, um zu bestätigen, ob der Benutzer abgebrochen hat (z. B. durch Drücken der Esc-Taste usw.). Wenn TRUE zurückgegeben wird, sollte der aktuelle Vorgang abgebrochen und ein positiver Fehlercode zurückgegeben werden.


(3.5) filterSelectorFinish-Aufruf:

Dieser Aufruf ermöglicht es dem Plug-in, nach der Verarbeitung aufzuräumen. Finish wird genau dann aufgerufen, wenn der Startaufruf erfolgreich ist (es wird kein Fehler zurückgegeben). Auch wenn bei continue ein Fehler auftritt, wird der Finish-Aufruf trotzdem ausgeführt. Achtung! : Seien Sie vorsichtig, wenn der Benutzer während eines Fortsetzungsanrufs abbricht, normalerweise dann, wenn Sie den nächsten Fortsetzungsanruf erwarten. Wenn der Benutzer abbricht, ist der nächste Anruf ein Abschlussanruf und kein Fortsetzungsanruf! ! ! .
Regeln: Wenn der Startaufruf erfolgreich ist, garantiert Photoshop, dass ein Fertigstellenaufruf eingeleitet wird.

(3.6) Fehlercodes
Plugins können Standardfehlercodes des Betriebssystems zurückgeben oder ihre eigenen Fehler (positive ganze Zahlen) melden. Es ist im SDK definiert:

#define filterBadParameters –30100 // #define filterBadMode –30101 // Dieses Modusbild wird nicht unterstützt

(4) Regentropfenfilter DEMO
Zuvor haben wir hauptsächlich über die Grundkenntnisse eines Filters gesprochen. Dann werden nur die wichtigsten Teile zur Erläuterung herausgegriffen und weitere technische Details können aus Platzgründen nicht abgeschätzt werden. Die Hauptgrundlage des oben Gesagten ist das Dokument von PS SDK6.0. Die Hauptregeln beziehen sich auf die Übersetzung des Originaltexts, und ein kleiner Teil des Inhalts gehört zu meiner persönlichen Praxis und meinem Verständnis (ich werde Farben verwenden, um das persönliche Verständnis zu unterscheiden). wenn ich Zeit habe).
Jetzt beginnen wir mit der Erklärung der Demo! ! ! Wirklich müde. . . .
Der Algorithmus des Regentropfenfilters verweist hauptsächlich auf eine ausländische Website. Dies ist die Adresse, die mir ein Internetnutzer in einer Antwort auf einen anderen Artikel mitgeteilt hat. Der Ursprung dieses Filters ist der Sphärisierungsalgorithmus (in PS gibt es diesen integrierten Filter). Wir werden den Algorithmus nicht vorstellen, da er zwar den Kern des Filters darstellt, aber nicht im Mittelpunkt dieses Artikels steht. Auf dieser Grundlage geben wir den Pseudocode des Wassertropfeneffekts an:

---Wassertropfeneffekt--------------------
Zufällig einen erzeugen An der Position cx, cy wird ein Radius R zufällig generiert,
                                                                               hat eine sphärische Verzerrung mit R als Radius an der Position cx, cy erstellt.
Fügen Sie an dieser Stelle das Glanzlicht und den Schatten des Wassertropfens hinzu.
Erstellen Sie im Wassertropfen eine Gaußsche Unschärfe im Format 3*3.
             ----------------------------------

(4.1) Pixelpositionierung
Wiederholen Sie den obigen Vorgang, um mehrere Wassertropfen zu erzeugen. Dies ist der Kernalgorithmus dieses Filters. Die konkrete Formel ist nicht angegeben. Um die Daten verarbeiten zu können, müssen wir jedoch verstehen, wie Pixeldaten in den von PS übergebenen Daten lokalisiert werden. Beispielsweise möchten wir die Pixeldaten des R-Kanals an der (x, y)-Position im Originalbild erhalten . Wie bekommen wir es? Hier stellen wir auch die wichtigen Datenelemente im Zusammenhang mit der Pixelpositionierung in FilterRecord vor. Sie sind vom Typ int32 und gehören zu den von PS für das Plug-in bereitgestellten Daten. Entspricht BitmapData.Stride in c#. Bitte beachten Sie jedoch, dass in inData und outData die Daten möglicherweise nicht nach 4 Byte ausgerichtet sind! Aber ps sagt nicht, dass es am Ende der Zeile keine redundanten Bytes gibt. Kurz gesagt handelt es sich um die Anzahl der Bytes (Span), die von einer Bilddatenzeile im Speicher belegt werden.
int16 inLoPlane, inHiPlane, outLoPlane, outHiPlane,
Gehört zu den Daten, die das Plug-in PS benachrichtigt, wenn es PS anfordert. Der Wert ist der erste Kanal und der letzte Kanalwert, der im angefordert wird Beachten Sie beim nächsten Vorgang, dass es sich bei diesem Wert um einen Indexwert mit 0 als Basis handelt. Für RGB-Bilder gibt es beispielsweise drei Kanäle, 0 bis 2, entsprechend B, G und R (beachten Sie, dass hier die Reihenfolge in der Datei beibehalten wird, nicht die übliche RGB-Reihenfolge in PS!!!). Wir können jeweils einen Kanal oder mehrere Kanäle gleichzeitig anfordern, und die Daten von mehreren Kanälen werden der Reihe nach verschachtelt. Wenn wir beispielsweise inLoPlane=0 und inHiPlane=2 festlegen, lautet die von PS bereitgestellte inData-Datenanordnung:
                                                                       1. Die uns von PS zur Verfügung gestellten inData sind: [G] [G] . ..
                                                       Suchen Sie ein Pixel wie folgt:
Zuerst wird die Anzahl der von uns angeforderten Kanäle auf Ebenen festgelegt: dann:
planes=inHiPlane-inLoPlane+1; //Number Anzahl der Kanäle
uint8 * pixels=(uint8*)inData ;
Wir erhalten den Kanaldatenausdruck mit Index k an der (x, y)-Position wie folgt:
pixels [ y * inRowBytes + x * planes + k ]; oder
*(Pixel + y * inRowBytes + x * Ebenen + k);
                                                                                                                                                                                                , y) Position ist wie folgt: x * 3 + 1 ] // p( x,y).G
pixels [ y * inRowBytes + x * 3 + 2 ]; // p(x,y).R

Okay, mit der obigen Grundlage können wir uns die folgende Gaußsche 3*3-Vorlagenverarbeitung ansehen: The Die Gaußsche 3*3-Vorlage lautet wie folgt:
1 2 1
2 4 2 /16
1 2 1
Wir verwenden die obige Pixelpositionierungsmethode, um den Inhalt der folgenden Schleifenverarbeitung einfach auszuschreiben :

Gaußsche Unschärfe (3*3-Vorlage)
sum=0;
// Verarbeiten Sie jeden Kanal nacheinander
für(k=0;kg_Planes;k++)
{
 
//unschärfe es!
sum+=bufferPixels[(j -1)*rowBytes+(i -1)*g_Planes +k];
sum
+=bufferPixels[(j-1)*rowBytes+(i)*g_Planes +k] *2;
Summe
+=bufferPixels[(j- 1)*rowBytes+(i+ 1)*g_Planes +k];
Summe
+=bufferPixels[j*rowBytes+(i -1)*g_Planes +k] *2;
    sum
+=bufferPixels[j*rowBytes+i*g_Planes +k]*4;
    sum
+=bufferPixels[j*rowBytes+(i+1)*g_Planes +k]*2;
    sum
+=bufferPixels[(j+1)*rowBytes+(i-1)*g_Planes +k];
    sum
+=bufferPixels[(j+1)*rowBytes +(i)*g_Planes +k]*2;
    sum
+=bufferPixels[(j+1)*rowBytes+(i+1)*g_Planes +k];
    sum
= Summe>>4;//即除以16
    Pixel[j*rowBytes+(i) *g_Planes +k]=sum;
}


(5) Fazit:
Schauen wir uns abschließend den Screenshot der Wirkung der Verwendung des Filters an: Wenn PS startet, scannt es die Plug-Ins in jedem Plug-In-Verzeichnis und lädt sie diese in das entsprechende Menü ein.
Eine Einführung in die Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop
Verarbeitungsergebnisse:
Eine Einführung in die Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop
Schließlich gibt es einen Download-Link für ein komprimiertes Paket dieses Filters:
RainDropFilter.rar
Die Installationsmethode lautet: Entpacken Sie die Datei und legen Sie sie einfach im Filterinstallationsverzeichnis von Photoshop ab. Für Photoshop CS kann das Filterinstallationsverzeichnis beispielsweise die Form haben:
C:ProgrammeAdobePhotoshop CS Plug-in Filter“.
Über PS Das SDK kann von der offiziellen Website von Adobe bezogen werden. Ich weiß nicht, ob es derzeit kostenlos ist. . . . .


(6) Referenzen:
(1) Photoshop SDK 6.0.
(2)Photoshop SDK CS.
(3) (Regentropfen-Filteralgorithmus) Filter: Regentropfen: http://www.php.cn/

-------- -- ------------------------------------------------ -- -
Anhang: Statement von Adobe SDK!
--------------------------------- --- --------------
// ADOBE SYSTEMS INCORPORATED
// Copyright 1993 - 2002 Adobe Systems Incorporated
// Alle Rechte vorbehalten
//
// ADOBE Systems Incorporated
// Copyright 1993 - 2002 Adobe Incorporated
// Alle Rechte vorbehalten.
//
// HINWEIS: Adobe erlaubt Ihnen, diese
// Datei gemäß den Bedingungen der ihr beigefügten Adobe-Lizenzvereinbarung
// zu verwenden, zu ändern und zu verteilen diese Datei von einer anderen Quelle
// als Adobe erhalten haben, bedarf Ihre Nutzung, Änderung oder Verbreitung
// davon der vorherigen schriftlichen Genehmigung von Adobe.
//
// Hinweis: Adobe gestattet Ihnen die Nutzung, Änderung und Verbreitung dieser Datei gemäß den Bedingungen der geltenden Adobe-Lizenzvereinbarung.
// Wenn Sie diese Datei von einem Nicht-Adobe-Anbieter erhalten haben, ist für Ihre Nutzung, Änderung und Verbreitung eine zuvor unterzeichnete Adobe-Lizenzvereinbarung erforderlich.
//----------------- ----------------------------------

Weitere Einführungen und verwandte Artikel zur Entwicklung von Filter-Plug-Ins von Drittanbietern für Photoshop finden Sie auf der chinesischen PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn