Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

GDI+ Tutorial


  • Please log in to reply
8 replies to this topic
nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012
GDI+ Tutorial:
 
GDI und GDI+ sind zwei Windows interne Gruppen von Funktionen die Hauptsächlich für die Verarbeitung(Darstellen,Bearbeiten,Erstellen,Laden,Speichern) von Bildmaterial gedacht sind.
 
Man kann mit GDI+ z.B.
  • Bilderformate umwandeln.
  • Bilder bearbaiten und darstellen.
  • Effekte über Bilder legen.
  • Bilder Analysieren.
  • Einfache 2D Spiele erstellen.
Ich werde alle diese Möglichkeiten später genauer erklären aber erstmal werden wir uns wohl eine Einleitung durchlesen müssen:
 
1.Einleitung: Vorteile:
  • GDI+ hat den Vorteil, dass es auf jedem Windowsrechner ab XP vorinstalliert ist also man keine Zusatzprogramme etc. "mitschleppen"
  • Hinzu kommt, dass es eine sehr schöne GDI+ lib von Tic gibt, die ihr Bedarf hier findet.
  • Weiterhin ist GDI+ einfach zu verstehen, und bietet dafür extrem viel Power.
Nachteile:
  • Der größte Nachteil von GDI+ ist, dass es keine Grafikartenbeschleunigung bietet und alle Berechnungen in der CPU ausgeführt werden müsen.
Um alles Zusammenzufassen ist GDI+ eine gute Wahl für diesen Aufgaben Bereich da es eigentlich ein Standard ist. Da man früher oder Später über solche Probleme stolpert ist es ein Must-Have, dass man lieber früher als Später lernen sollte.
 
 
1.Einführung:Farbenlehre
Wie ich bereits gesagt habe findet ihr hier eine lib von Tic (a great thanks to him from my side) diese müsst ihr haben, da dieses Tutorial darauf aufbaut.
 
GDI sowie GDi+ folgen beide jeweils einem Grundprinzip. Wenn man dieses Verstanden hat kann man sich den Rest selber beibringen.
 
Die Farben im Computer bestehen aus 4 Channels die alle Werte von 0-255 enthalten können (8 bit und 8*4=32 bit für eine Farbe)
3 Channels sind Farben:
  • R = Rot (Red)
  • B = Blau (Blue)
  • G = Grün (Green) 
Der letzte Channel ist die Durchsichtigkeit:
  • A = Durchsichtigkeit (Alpha)
Farben werden im normalerweise Hexa-Dezimahl_Zahlen-System angegeben.
Dabei stehen zwei Hexzeichen für einen Channel:
z.B. Weiß
  • R: 0xFF
  • G: 0xFF
  • B: 0xFF
  • A: 0xFF ;voll sichtbar da höchste Zahl
Bei GDI/GDI+ werden Zahlen in der Form ABGR angegeben.
Also wenn man alles zusammen fügt
0xFFFFFFFF
Es ist wichtig, das man sich dies merkt denn wenn man Channels Vertauscht kommen manchmal ganz komische Farben raus.
  • 0xFF00FF00 = Grün
  • 0xFFFF0000 = Blau
  • 0x00FFFF00 = Durchsichtig
1.Einführung:Typen
Nein ich rede nicht von Menschen sondern von Datentypen. Wir werden im folgenden einfach von Typen sprechen selbst wenn ihr nicht genau versteht was es ist.
 
Bei GDI/GDI+ sindz.B. die folgenden Typen wichtig:
  • pBitmap (ein GDI+ Bild)
  • hBitmap (ein GDI Bild)
  • pGraphics (Die Zeichen oberfläche von GDI+)
  • DC (Damit kann man auf Controls wie z.B. Buttons zeichnen.)
  • u.v.m.
1.Einführung Startup
Den ersten typen den wir kennenlernen heißt pToken:


pToken:=Gdip_Startup()
Bevor man GDI+ benutzen kann muss man GDi+ hochfahren.
Das bewirkt diese Funktion.
Das pToken ist wieder wichtig wenn man GDI+ herunterfährt:
 
1.Einführung:Shutdown


Gdip_shutdown(pToken)
Danach ist GDI+ heruntergefahren und man kann die Funktionen nicht mehr benutzen.
Da das verfrühte Runterfahren häufig eine Fehlerquelle ist benutzt man diese Funktion wirklich erst wenn man weiß, dass man kein GDI+ mehr benötigt.
 
1.Einführung:Lade/Speicher/Erstell/Umwandlungs Funktionen
Diese Befehle werden meistens benutzt um die standard Bilder Typen zu erstellen:
  • pBitmap:=Gdip_CreateBitmap(w,h) ;erstellt eine pBitmap mit der höhe h und der weite w
  • pBitmap:=Gdip_CreateBitmapfromHBITMAP(hBitmap) ;erstellt eine pBitmap von einer hBitmap, die hBitmap bleibt erhalten
  • pBitmap:=Gdip_CreateBitmapFromFile(filename) ;lädt eine Bild Datei und schreibt die Ergebnisse in pBitmap.(Endungen z.B. png,bmp,jpg,ico,tif)
  • Gdip_SaveBitmapToFile(pBitmap,filename) ;speichert pBitmap in eine neue Bilddatei siehe CreateBitmapFromFile
  • Gdip_DisposeImage(pBitmap) ,löscht eine nicht mehr gebrauchte pBitmap
  • hBitmap:=Gdip_CreateHBITMAPfrompBitmap(pBitmap) ;siehe CreatepBitmapFromHBITMAP
  • gdip_DeleteObjekt(hObjekt (z.B. hBitmap)) ; löscht ein nicht mehr gebrauchtes Objekt.
  • pGraphics:=Gdip_GraphicsfrompBitmap(pBitmap) ;erstellt eine pGraphics von einer pBitmap und verlinkt beide.
2.Bild Formate ineinander Umwandeln
 
Ein paar dieser Befehle können wir benutzen um Bilder von einem Bildformat in das andere umzuwandeln.
Das script ist sehr kurz und einfach (ein 5 Zeiler). 
In unserem Beispiel wollen wir test.png in test.jpg umwandeln.
Bilder zum testen könnt ihr mit Paint oder GIMP erstellen.
 
Bevor wir GD+ benutzen können müssen wir es hochfahren:
pToken:=gdip_Startup()
danach laden wir das Bild test.png (diese Datei befindet sich im Script Ordner).
Bild:=Gdip_CreateBitmapFromFile("test.png")
Die Variable Bild bekommt daraufhin einen Zeiger zugewiesen, der angiebt wo im Speicher die pBitmap liegt.
Man sollte diesen zeiger nicht verändern, bis die pBitmap gelöscht ist, sonst bekommt man Probleme wie z.B. einen Memory Leak.
 
 
Warning Memory Leak:
Spoiler

 
Warning Access Violation:
Spoiler

Als nächstes speichern wir dieses Bild einfach wieder, aber mit neuer Dateiendung:
Gdip_SaveBitmapToFile(Bild,"test.jpg")
Wir könnten hier das Script jetzt eigentlich per ExitApp beenden, aber da auch das Aufräumen gelernt werden muss tut man dies auch:
Zuerst das Bild löschen:
Gdip_DisposeImage(Bild)
Danach GDI+ herunterfahren:
Gdip_Shutdown(pToken)
Wenn man nun alles Zusammen fügt erhält man das folgende Script:
pToken:=gdip_Startup()
Bild:=Gdip_CreateBitmapFromFile("test.png")
Gdip_SaveBitmapToFile("test.jpg",Bild)
Gdip_DisposeImage(Bild)
Gdip_Shutdown(pToken)

Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

3:Bilder bearbeiten und Darstellen
 
Um mit GDI+ zeichnen zu können benötigt man Wissen über die so genannten Zeichenbefehle:

  • gdip_DrawRectangle(pGraphics,pPen,x,y,w,h) ;zeichnet den Rahmen eines Rechtecks auf eine pGraphics
  • gdip_FillRectangle(pGraphics,pBrush,x,y,w,h) ;zeichnet das Innere eines Rechtecks auf eine pGraphics
  • gdip_DrawRoundedRectangle(pGraphics,pPen,x,y,w,h,r) ;zeichnet den Rahmen eines Rechtecks mit runden Ecken
  • gdip_FillRoundedRectangle(pGraphics,pBrush,x,y,w,h,r) ;zeichnet das Innere eines Rechtecks mit runden Ecken.

Das sollte fürs erste reichen. Nur Bahnhof verstanden?
Das war auch so geplant:
Das sind Zeichenbefehle. Damit zeichnet man auf eine pGraphics welche man z.B. mit dem Befehl GraphicsFromBitmap erstellen kann. Wenn man dann auf die pGraphics zeichnet zeichnet man auch auf die Bitmap, von der man die pGraphics erstellt hat.

Die meisten Funktionen zeichnen Formen. Hier z.B. Rechteck.
Jede Form kann man auf Zwei verschiedene Arten zeichnen:
Man kann den Rand zeichnen oder die Form mit einer Farbe ausfüllen. Die erste Art von Zeichenfunktion heißt Draw die zweite Fill wie in den oben Genannten Funktionen
 
Die folgenden Formen sind schon standardmäßig in der GDI+ lib vorhanden:

  • Rechteck (Rectangle) siehe oben
  • Rechteck mit Runden Ecken (RoundedRectangle) siehe oben
  • Ellipse (Ellipse)
  • Halbe/Viertel Kreise etc (Pie)

Doch wie seiht es genau aus wenn ich auf meine pBitmap Zeichne ?
Wie ich oben bereits gesagt habe kann man nicht direkt auf eine pBitmap zeichnen sondern muss eine pGraphics der pBitmap erstellen.
Jedoch zuerst GDI+ starten.



pToken:=gdip_Startup()
NeuesBild:=gdip_CreateBitmap(800,600)

Die zweite Zeile erstellt eine neue Bitmap mit den Maßen 800x600.
Jetzt die pGraphics erstellen.

neuepGraphics:=gdip_GraphicsFromImage(NeuesBild)

Wir sind aber noch nicht fertig mit Vorbereiten:
Die Zeichen-Funktionen brauchen noch einen Parameter den wir Vorbereiten müssen.
Die Draw-Funktionen brauchen einen Parameter vom Typ pPen.
Die Fill Funktionen noch einen Parameter vom Typ pBrush.
Der pPen gibt an wie eine Linie aussehen soll, der pBrush gibt an wie etwas ausgefüllt werden soll.
Man kann beide per Funktionen erstellen:

  • pPen:=gdip_CreatePen(color,width)
  • pBrush:=gdip_BrushCreateSolid(color)

Da wir nun fast alle Parameter der Funktionen kennen, sollten wir festlegen, was wir zeichnen wollen.
Ich wäre für einen weißen Kreis(Rahmen) auf schwarzem Hintergrund:
Den Hintergrund füllen wir einfach mit einem Rechteck, das so groß ist wie der Hintergrund.
Darauf dann den Rahmen eines Kreises.
Für den Hintergrund nehmen wir die Fill Zeichenart also benötigen wir ein pBrush:

SchwarzFüllen:=gdip_BrushCreateSolid(0xFF000000)

Auf unsere neuepGraphics zeichnen wir dann ein schwarzes Rechteck mit x=0 y=0 und w=800 und h=600.

gdip_FillRectangle(neuepGraphics,schwarzFüllen,0,0,800,600)

Für den Kreis müssen wir die Draw Zeichenart benutzen. Dafür benötigen wir einen pPen:

WeisserStift:=gdip_CreatePen(0xFFFFFFFF,5)

Wir haben nun einen WeißenStift mit der Dicke 5.
Um einen Kreis zu zeichnen benötigen wir die Form Ellipse die Syntax lautet so:
gdip_DrawEllipse(pGraphics,pPen,x,y,w,h)
Damit der Kreis in der Mitte landet müssen wir ein bischen umrechnen:
Da xund y die Linke obere Ecke und nicht den Mittelpunkt benutzen muss man um auf den Mittelpunkt zu gelangen die folgende Berechnung verwenden:
x=xMitte-r
y=yMitte-r
w=2*r
h=2*r
Wenn wir also nun einen Kreis mit dem Radius 100 und dem Mittelpunkt (400|600) erstellen wollen müssen wir nur noch die Werte in die Formel setzen und ausrechnen.
Das Ergebnis x=300 y=200 w=200 h=200

gdip_DrawEllipse(neuepGraphics,WeisserStift,300,200,200,200)

Man sollte pPens und pBrushes sowie pGraphics sowie alle anderen sogenannten Recourcen löschen sobald man sie nicht mehr braucht.

gdip_deletePen(WeisserStift)
gdip_deleteBrush(SchwarzFüllen)
gdip_deleteGraphics(neuepGraphics)

Fertig gezeichnet. Hier könnt ihr jetzt euer Ergebnis überprüfen falls ihr wollt.
Speichert einfach dazu das Bild wie ich es euch im letzten Kapitel gezeigt habe.
 
Darstellen:
Wir wollen unser Bild noch auf einer Gui darstellen.
Dazuschauen wir uns doch einfach mal an was wir alles gemacht haben undmachen werden:

  • GDI+ gestartet.
  • Eine Bitmap mit den Maßen 800*600 erstellt sowie die pGraphics davon erhalten.
  • Auf diese Graphics dann einen Weißen Kreis auf schwarzem Hintergrund gezeichnet.
  • Aufgeräumt.
  • Eine GUI mit den Maßen 800*600 erstellen (ohne Rand (-Caption)), die HWND dieses GUIs bestimmen.
  • Über die HWND den Device Kontext (DC) bestimmen. Dann eine pGraphics von der DC bestimmen.
  • Unsere pBitmap in die pGraphics des DC kopieren.
  • Aufräumen und GDI+ runterfahren.

Die Schritte 5 und 8 werden nicht mehr explizit erklärt, bleiben die Schritte 6 und 7.
 
Den Device Context eines Controls oder Fesnsters kann man mit der HWND bestimmen.
Dafür benutzt man die Funktion GetDC:

GuiDC:=GetDC(hWND)

Wie ich bereits erwähnt habe kann man auf diesen Device Context zeichnen, ähnlich wie man auf eine pBitmap zeichnet.
Wenn man auf den DC eines Controls zeichnet wird alles was in den DC gezeichnet wird dargestellt, bei mehreren Schritten erst nacheinander.
Wenn ihr also mehrere Zeichenschritte ausführen sieht man ein Flackern.
Da wir jedoch unser Bild schon im Hintergrund fertig gezeichnet haben, benötigen wir nur noch einen Schritt.
Um jedoch auf einen DC zu zeichnen (wie bei der pBitmap) braucht man eine pGraphics:

DCGraphics:=gdip_GraphicsFromHDC(GuiDC)

In diese pGraphics kopieren wir einfach unsere ganze pBitmap:

gdip_drawImage(DCGraphics,NeuesBild)

Danach ist unser Bild dargestellt.
Jetzt müssen wir noch aufräumen und GDI+ falls wir es nicht mehr verwenden wollen runterfahren:

gdip_deleteGraphics(DCGraphics)
ReleaseDC(GuiDC)
gdip_disposeImage(neuesBild)
gdip_Shutdown(ptoken)

Zusammen incl. der nicht beschriebenen Teile ergibt das dann das folgende Script:

pToken:=gdip_Startup()
NeuesBild:=gdip_CreateBitmap(800,600)
neuepGraphics:=gdip_GraphicsFromImage(NeuesBild)
SchwarzFüllen:=gdip_BrushCreateSolid(0xFF000000)
gdip_FillRectangle(neuepGraphics,schwarzFüllen,0,0,800,600)
WeisserStift:=gdip_CreatePen(0xFFFFFFFF,5)
gdip_DrawEllipse(neuepGraphics,WeisserStift,300,200,200,200)
gdip_deletePen(WeisserStift)
gdip_deleteBrush(SchwarzFüllen)
gdip_deleteGraphics(neuepGraphics)
Gui,-Caption +lastfound
Gui,show,w800 h600,abc
HWND:=WinActive()
GuiDC:=GetDC(HWND)
DCGraphics:=gdip_GraphicsFromHDC(GuiDC)
gdip_drawImage(DCGraphics,NeuesBild)
gdip_deleteGraphics(DCGraphics)
ReleaseDC(GuiDC)
gdip_disposeImage(neuesBild)
gdip_Shutdown(ptoken)

Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

4. Bildeffekte:
Bildeffekte sind dazu da um entweder Bilder zu verbessern z.B. Rote Augen,Bildschärfe... oder sie generell nach einem Muster zu verändern.
Vorweg sei gesagt, dass ich mich nicht perfekt damit auskenne - Ich will nur Wege aufzeigen mit denen man Bildeffekte realisieren kann.
Man kann auch hierbei in verschiedene Bereiche aufteilen, ich jedoch nicht.
 
Hier ist das Original verwendete Testbild:


Ich werde 2 Möglichkeiten aufzeigen:
Zuerst einfache Farb- und Positions- sowie Ausdehnungstransformationen und Verschiebungen, dann komplexere Bildeffekte.
 
Die einfachen Bildeffekte können alle mit den Funktionen

  • Gdip_DrawImage
  • Gdip_DrawImagePointsRect

erzeugt werden.
Zuerst der DrawImage Befehl:
Der DrawImage Befehl bietet ziemlich einfach die Möglichkeit nur bestimmte Bereiche eines Bildes zu kopieren oder zurück zu schreiben.
So könnte man ein Bild Vergrössern verkleinern...
Dafür verwendet man diese Parameter:

Gdip_DrawImage(pGraphics, pBitmap, dx="", dy="", dw="", dh="", sx="", sy="", sw="", sh="", Matrix=1)

dx bedeutet Destination X und ist die X Koordinate des Pixels ab dem der Kopierte Bereich auf der pGraphics eingefügt wird.
dy ist das Gleiche bloß für die Y-Koordinate.
dw ist die Weite, des Bereiches in den hineinkopiert wird, ausgehend von dx.
dh ist das gleiche bloß für die Höhe ausgehend von dy.
sx sy sw sh bedeuten jeweils das selbe, außer, dass sie für die Quelle sind, also den Bereich bestimmen der Kopiert werden soll.

Jetzt könnte man mit dieser Funktion das Bildes vergrößern und dann nochmal Unvergrößert auf dem Vergrößerten Teil darstellen.
Vergrößert wird das Bild wenn die Zielweite oder Zielhöhe grösser sind als das eigentliche Bild.
Das Bild wird dann von der Funktion automatisch auf die Zielgrößen angepasst und dabei in der Ausdehnung angepasst.
 
Hier die oben angesprochene Idee als Script:
Hierbei wird das Bild um das 1.2-fache skaliert und dann die Originalversion oben drauf kopiert

SetBatchlines,-1
;Init
#Include <gdip>
pToken:=gdip_startup()
LoadedImage:=Gdip_CreateBitmapFromFile("Test.jpg") ;bild laden
W:=Round((apw:=Gdip_GetImageWidth(LoadedImage))*1.2,0) ;in W die 1.2 fache Größe des Bildes abgelegt
;in apw die Original Größe
H:=Round((aph:=Gdip_GetImageHeight(LoadedImage))*1.2,0) ;selbe für H und aph
;GUI
Gui,add, Text, x0 y0 w%w% h%h% hwndDrawArea,Loading...
Gui,Show,% "w" w " h" h
;GDI auf GUI Zeug
DrawAreaDC:=GetDC(DrawArea)
GDrawArea:=gdip_graphicsfromHDC(DrawAreaDC)
BufferBitmap:=Gdip_CreateBitmap(w,h)
BufferGraphics:=gdip_GraphicsfromImage(BufferBitmap)
;
Gdip_DrawImage(BufferGraphics, LoadedImage,0,0,W,H) ;Bild skaliert auf die BufferGraphics zeichnen
Gdip_DrawImage(BufferGraphics, LoadedImage,Round(apw*0.1,0),Round(aph*0.1,0),apw,aph) ;Original Bild zentriert oben drauf zeichnen
Draw:
Gdip_DrawImage(GDrawArea, BufferBitmap)
return
GuiClose:
ExitApp

Die Datei Test.jpg muss sich im Script Ordner befinden!
Ziemlich simpel und nicht unbedingt schön das Ergebnis, oder?
Viele Möglichkeiten bietet das nicht.
Interessant ist der letzte Parameter:



Gdip_DrawImage(pGraphics, pBitmap, dx="", dy="", dw="", dh="", sx="", sy="", sw="", sh="", Matrix=1)

Matrix was bedeutet das?
Eine Matrix ist ein Begriff den vielleicht der eine oder andere aus der Schulzeit aus dem Mathe Unterricht kennt.
An sich ist eine Matrix ein 2 Dimensionales Konstrukt aus Zahlen mit denen eine Liste von Werten verrechnet werden.
So kann man ziemlich einfach Werte miteinander verrechnen.
In diesem Fall wird es benutzt um die Farben eines Pixels miteinander zu verrechnen.
Jedoch erstmal eine kurze Einführung in Matrizen:
 
Matrizen:
Matrizen sind wie bereits gesagt 2-Dimensionale Zahlen Listen (Man könnte Array sagen) z.B:
[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[0,0,0,1]
Diese werden in unserem Fall nur mit einer 1-Dimensionalen Liste von Zahlen multipliziert:

[m11,m12,m13,m14]
[m21,m22,m23,m24] 
[m31,m32,m33,m34]*[l1,l2,l3,l4]
[m41,m42,m43,m44]
=[[m11,m12,m13,m14]*[l1,l2,l3,l4],[m21,m22,m23,m24]*[l1,l2,l3,l4],[m31,m32,m33,m34]*[l1,l2,l3,l4],[m41,m42,m43,m44]*[l1,l2,l3,l4]]
=[l1*m11+m12*l2+l3*m13+l4*m14,l1*m21+l2*m22+l3*m23+l4*m24,l1*m31+l2*m32+l3*m33+l4*m34,l1*m41+l2*m42+l3*m43+l4*m44]

Damit kann man alle Möglichen Additionen der Ursprungszahlenliste miteinander darstellen.

In GDI+ wird allerdings keine Einfach Matrix verwendet, sonder eine erweiterte.
Da wir 4 Kanäle haben, bräuchten wir nur eine 4x4 Matrix um die Farben miteinander Rekombienieren zu können.
Es wird jedoch eine 5x5 Matirx verwendet.
Der Rechte Rand wird dazu benutzt um zusätzlich auch noch Additionen durchführen zu können.

[...,m15]
[...,m25]
[...,m35]*[l1,l2,l3,l4]
[...,m45]
=[..+m15,..+m25,..+m35,..+45]

Die unterste Zeile solltet ihr eigentlich immer bei [0,0,0,0,1] lassen.
Ich hab nicht gerafft was die macht wink.png
 
Wie gesagt werden damit die Farben eines Pixels verrechnet.
Dafür werden die einzelnen Werte der Farbkanäle auf einen Bereich von 0-1 "geclampt", und sind nun Float werte. !Wichtig!
 
geclampt bedeutet einfach dass sie in diesen Bereich gesteckt werden, alles was kleiner als dieser Bereich ist entspricht dem kleinsten Wert und alles was zu groß ist dem größten.
Jetzt habt ihr erstmal genug wissen um mit diesem Script rum zuspielen:

SetBatchlines,-1
#SingleInstance,Force
Gui,add,picture,hwndhwnd,Test.jpg
If !Gdip_startup()
    Msgbox % "GDI+ lib wurde leider nicht gefunden" 
LoadedImage:=Gdip_CreateBitmapFromFile("Test.jpg")
HDC:=GetDC(hwnd+0)
G:=Gdip_GraphicsFromHDC(HDC)
OnMessage(0xF,"WM_Paint")
W:=Gdip_GetImageWidth(LoadedImage)
H:=Gdip_GetImageHeight(LoadedImage)
Loop 5
{
    X:=A_Index
    Loop 5
        Gui,add,Edit,% "x" . (X*40-20) . " y" . (H-16+24*A_Index) . " w30 h20 vMatrix" . X . A_Index,% (X=A_Index)
}
Gui,Add,Button,x19 w192 h30 gPress,Test
Gui,Show
return

Press:
Gdip_GraphicsClear(G, ARGB=0x00ffffff)
matrix:=CreateMatrix()
Gdip_DrawImage(G, LoadedImage, "","", "", "", "", "", "", "", matrix)
return 

GuiClose:
ExitApp


WM_Paint()
{
global
Critical
Gdip_DrawImage(G, Bitmap, "","", "", "", "", "", "", "", matrix)
}

CreateMatrix()
{
Global
Gui,Submit,NoHide
ret:=""
Loop 5
{
    X:=A_Index
    Loop 5
        ret.= Matrix%X%%A_Index% . "|"
}
StringTrimRight,ret,ret,1
return ret
}

Ein paar Beispiel Matrizen:
Negativ:
[-1,0,0,0,1]
[0,-1,0,0,1]
[0,0,-1,0,1]
[0,0,0,1,0]
[0,0,0,0,1]
Grau:
[0.33,0.33,0.33,0,0]
[0.33,0.33,0.33,0,1]
[0.33,0.33,0.33,0,1]
[0,0,0,1,0]
[0,0,0,0,1]
Farben vertauscht:
[0,0,1,0,0]
[1,0,0,0,0]
[0,1,0,0,0]
[0,0,0,1,0]
[0,0,0,0,1]
Ganz Normal:
[1,0,0,0,0]
[0,1,0,0,0]
[0,0,1,0,0]
[0,0,0,1,0]
[0,0,0,0,1]
 

Diese Matrix wird über den Parameter Matrix übergeben.

Es ist dann einfach ein String bei dem Zwischen den Zahlen Trennzeichen benutzt werden.

So wie ich es aufgeschrieben habe ist nur ein Beispiel.

Es geht auch ein komplett andere Form wie z.B. "-1|0|0|0|0|0|-1|0|0|0|0|0|-1|0|0|0|0|0|1|0|0|0|0|0|1" oder 

 

(

1.5 |0 |0 |0 |0

0 |1.5 |0 |0 |0

0 |0 |1.5 |0 |0

0 |0 |0 |1 |0

0.05 |0.05 |0.05 |0 |1

)

 

 

Man kann diese Form der Farbveränderung auch mit einer Verschiebung kombinieren.

Damit kann man einen einfachen Blur-Effekt (Bewegungsunschärfe) erzeugen.

Dafür setze ich den Alpha Wert (die Durchsichtigkeit) runter und verschiebe dann das Bild auf sich selber (Kann schlecht aussehen bei Bilden mit Alpha Channel(wie die anderen Effekte auch))

SetBatchlines,-1
;Init
#Include <gdip>
pToken:=gdip_startup()
LoadedImage:=Gdip_CreateBitmapFromFile("Test.jpg")
W:=Gdip_GetImageWidth(LoadedImage)
H:=Gdip_GetImageHeight(LoadedImage)
;GUI
Gui,add, Text, x0 y0 w%w% h%h% hwndDrawArea,Loading...
Gui,Show,% "w" w " h" h
;GDI to GUI stuff
DrawAreaDC:=GetDC(DrawArea)
GDrawArea:=gdip_graphicsfromHDC(DrawAreaDC)
BufferBitmap:=Gdip_CreateBitmap(w,h)
BufferGraphics:=gdip_GraphicsfromImage(BufferBitmap)
Gdip_DrawImage(BufferGraphics, LoadedImage) 
Count:=10 ;das Bild wird 20 mal ein bisschen nach rechts verschoben mit vermindertem 
Loop % Count 
Gdip_DrawImage(BufferGraphics, LoadedImage,A_Index,0,W-A_Index,H,0,0,W-A_Index,H,"1,0,0,0,0|0,1,0,0,0|0,0,1,0,0|0,0,0," 1/Count ",0|0,0,0,0,1") ;
Draw:
Gdip_DrawImage(GDrawArea, BufferBitmap)
return
GuiClose:
ExitApp

Komplexere Effekte lassen sich damit jedoch nicht erzeugen, da die Verrechnungsmethoden auf das Addieren einer Gruppe von Pixeln zu einer anderen Gruppe die mit einer Matrix multipliziert ist.

Man kann nicht auf einzelne Pixel zugreifen.

 

Jedoch geht auch das mit GDI+:

Mit den Funktionen SetPixel und GetPixel kann man auf die einzelnen Pixel Werte zugreifen.

Gdip_GetPixel(pBitmap, x, y)
Gdip_SetPixel(pBitmap, x, y, ARGB)

So könnte man z.B. Einen Channel getrennt von den anderen Kopieren.


Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012
Reserved

Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

Well that escalated Quickly.
:D

Leider hab ich nicht genug Zeit um alles auf einmal abzutippen.

Deshalb bekommz ihr es Ratenweise


Visit the new forum ahkscript.org.

http://ahkscript.org


xXMotionstylerXx
  • Members
  • 84 posts
  • Last active: Jan 15 2016 08:06 AM
  • Joined: 06 Apr 2013
y++
Msgbox, Vielen Dank für schon mal fie Einführung ;)

Eric

nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

Ich hab noch mal etwas hinzugefügt.


Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

Thema 3 vollständig


Visit the new forum ahkscript.org.

http://ahkscript.org


nnnik
  • Members
  • 1625 posts
  • Last active: Apr 11 2017 02:13 PM
  • Joined: 28 Jul 2012

Ich hab nochmal einen Fehler entdeckt und verbessert.


Visit the new forum ahkscript.org.

http://ahkscript.org