Autor Beitrag
obbschtkuche
Gast
Erhaltene Danke: 1



BeitragVerfasst: Mi 30.07.03 22:57 
GDI+

1. Was ist überhaupt das "GDI"?

Das GDI ist seit der ersten Version von Windows die Schnittstelle für Grafikausgaben aller Art. Seit Windows XP hat Microsoft eine neue, überarbeitete Version in Windows eingeführt. Beim GDI+ sind verschiedene neue Funktionen hinzugekommen, das Problem dabei ist jedoch, dass nur bei Windows XP Standardmäßig eine Unterstützung dafür vorhanden ist. Allerdings läßt sich alles nach inklusive Windows 98 Aufrüsten (Siehe Link am Ende)
Folgende neue Funktionen sind hinzugekommen:

  • Transformationen:
  • Rotierung
  • Skalierung
  • Verschiebung
  • Grafikausgabe:
  • Cardinal SPlines (Kurven, die beliebig viele Punkte berühren)
  • Unterstützung von JPEG, TIFF, PNG, ...
  • Textausgabe:
  • Zentrierter, Rechtsbündiger Text
  • Tab-Stopps
  • ...


2. Möglichkeiten

Es gibt mehrere Möglichkeiten das neue GDI zu nutzen. Entweder man nutzt eine Headerdatei,
wie ich sie z.B. hier hochgeladen habe. Man kann auch Komponenten nutzen, wobei man sich dann in der Regel nicht mehr um die Header zu kümmern braucht. (hier habe meine vorgestellt). Ich werde hier nur auf die Verwendung der Header eingehen, dabei sollte es auch möglich sein, andere Übersetzungen zu nutzen.

3. Grundgerüst

Das Grundgerüst jeder GDI+ Zeichenoperation sieht folgendermaßen aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
 graphic: GGraphics;
begin
 graphic := GGraphics.Create(DeviceContext);
 try
  // Zeichenoperationen
 finally
  graphic.free;
 end;
end;


Alternativ kann man natürlich auch auf die Variable verzichten indem man das ganze in einen with-try-finally Block einbaut.

4. Zusatzmethoden

Ich nutze folgende Zusatzmethoden, die einige Tipparbeit ersparen können (auch wenn hier nicht alle gebraucht werden):

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function RGBToColor(r,g,b: byte): color;
begin
 result.New(r,g,b);
end;

function ARGBToColor(a, r,g,b: byte): color; overload;
begin
 result.New(a,r,g,b);
end;

function ARGBToColor(argb: cardinal): color; overload;
begin
 result.New(argb);
end;

function MakePoint(x,y: integer): point;
begin
 result.New(x,y);
end;

function MakePointF(x,y: single): pointf;
begin
 result.New(x,y);
end;


5. Zeichnen von Bildern und Transformationen

Die einfachste Bild-Zeichen-Methode sieht folgendermaßen aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
var
 graphic: GGraphics;
 img: Image;
begin
 graphic := GGraphics.Create(Canvas.Handle);
 try
  // Bild öffnen
  img := Image.Create('knorkwarz1.bmp');
  try
   // Bild zeichnen
   graphic.DrawImage(img, 1010);
  finally
   // Bild freigeben
   img.Free; 
  end;
 finally
  graphic.free;
 end;
end;


Hier wird zuerst das Bild geöffnet, an Position 10,10 gezeichnet und wieder freigegeben.
Ein Hinweis zu FromFile: Die Funktion ist eine Klassenmethode, also muss man Image.FromFile('...') schreiben. Die Rückgabe ist zwar eine neue Instanz vom Typ Image, die man auch wieder Ordungsgemäß freigeben sollte. Richtig ist also img := image.FromFile('dateiname')

Jetzt wollen wir unser Bild noch Drehen, danach verschieben und zuletzt wieder in der Ursprünglichen Form zeichnen.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
var
 graphic: GGraphics;
 img: Image;
begin
 graphic := GGraphics.Create(Canvas.Handle);
 try
  // Bild öffnen
  img := Image.Create('Bild.bmp');
  try
   // Komplette Leinwand um 20° drehen
   graphic.RotateTransform(20);
   // Bild zeichnen
   graphic.DrawImage(img, 1010);
   // Um 20 Pixel jeweils nach unten und nach rechts Verschieben
   graphic.TranslateTransform(2020);
   // Bild zeichnen
   graphic.DrawImage(img, 1010);
   // Ursprünglichen Zustand wiederherstellen (für eventuelle weitere Zeichenoperationen)
   graphic.ResetTransform;
   // Bild freigeben
  finally
   img.Free;
  end;
 finally
  graphic.free;
 end;
end;


Je nach Größe des Bildes kann es sein, dass sich die Bilder überlappen. Am besten ist es, jede Zeile einmal auszuklammern und die Werte zu ändern, damit man sieht, was passiert.

Man sieht, dass Transformationen nicht nur eine Zeichenoperation erhalten bleiben, sondern so lange, bis entweder mit SetTransform(matrix) eine Transformationsmatrix geladen wird, oder mit Resettransform wieder der Ursprüngliche Zustand hergestellt wird.

6. Textausgabe

Wenn man zum Text kommt, wird das Ganze schon etwas umständlicher.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
procedure TForm1.Button2Click(Sender: TObject);
var
 graphic: GGraphics;
 brush: SolidBrush;
 font: GFont;
 col: GpColor;
 pt: Gppointf;
begin
 graphic := GGraphics.Create(Canvas.Handle);
 try
  // Mit weiß füllen
  col.new(255,255,255);
  graphic.Clear(col);
  // Ist später die Farbe des Textes
  col.new(255,0,0);
  brush := SolidBrush.Create(col);
  try
   // Die Schrift erstellen. Achtung: das G vor dem hinteren
   // Font nicht vergessen.
   // Der vordere Parameter ist die Schriftart, der hintere
   // die Größe
   font := GFont.Create('times'30);
   try
    // Die Position des Textes
    pt.new(10,10);
    // Text ausgeben
    graphic.DrawString('Test', -1, font, pt, brush);
    // Schrift und brush freigeben
   finally
    font.free;
   end;
  finally
   brush.Free;
  end;
 finally
  graphic.free;
 end;
end;


Bei GFont.Create(...) lassen sich auch mehr als 2 Parameter angeben. Beispiel:

font := GFont.Create('times', 10, FontStyleBold or FontStyleUnderline, UnitMillimeter);

für fetten, unterstrichenen, 10 Millimeter hohen Text.
Für FontStyle... lassen sich folgende Werte eintragen (Die auch mit or verknüpft werden können):

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
FontStyleRegular ......Normal (Standard)
FontStyleBold .........Fett
FontStyleItalic .......Kursiv
FontStyleBoldItalic ...Fett + Kursiv (FontStyleBold or FontStyleItlic)
FontStyleUnderline ....Unterstrichen
FontStyleStrikeout ....Durchgestrichen

Für Unit... sind folgende Werte interessant:
ausblenden Quelltext
1:
2:
3:
4:
5:
UnitPixel .............Jede Einheit ist ein Pixel   
UnitPoint .............Jede Einheit ist ein Punkt eines Druckers oder 1/72 Inch
UnitInch ..............Jede Einheit ist ein Inch
UnitDocument ..........Jede Einheit ist 1 / 300 Inch
UnitMillimeter ........Jede Einheit ist ein Millimeter


Selbstverständlich sind Transformationen auch für Text.

7. Cardinal SPlines und Linien

Wenn man sich die Deklaration von DrawCurve ansieht,
ausblenden Delphi-Quelltext
1:
function Graphics.DrawCurve(const pen: Pen; points: PointF; count: integer): Status;					

Fällt auf dass weder ein Array noch ein Pointer vorhanden ist. Allerdings funktioniert es wenn man das erste Element eines Arrays übergibt.

Hier jetzt noch ein Beispiel zur Verwendung:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
var
 graphic: GGraphics;
 pen: GPen;
 col: gpcolor;
 i: integer;
 pts: array[0..3of point;
begin
 graphic := GGraphics.Create(Canvas.Handle);
 try
  // Mit weiß füllen
  col.new(255,255,255);
  graphic.Clear(col);
  // Pen in rot mit Dicke 1.5 erstellen
  pen := GPen.Create(255001.5);
  // alles um 100 Pixel nach unten und rechts verschieben
  Graphic.TranslateTransform(100,100);
  // Kurven mit unterschiedlicher Spannung zeichnen
  pts[0] := MakePoint(0,0);
  pts[1] := MakePoint(40,70);
  pts[2] := MakePoint(150,90);
  pts[3] := MakePoint(200,30);
  for i := 0 to 8 do
   graphic.DrawCurve(pen, pts[0], 4, i/2);
  // Nach eine schöne Linie:
  graphic.ResetTransform;
  Graphic.TranslateTransform(0,30);
  graphic.DrawLine(pen, 10250400,300);
  // Und ein Rechteck
  graphic.DrawRectangle(pen, 40,60,310,170);
  // Und einen Kreis
  graphic.DrawEllipse(pen, 370,0,100,100);
 finally
  graphic.free;
 end;
end;


Die Funktionen für das Füllen von Rechtecken und Ellipsen heißen FillRectangle und FillEllipse.

So, ich habe jetzt genug für Heute, morgen mache ich vielleicht den 2. Teil. Dort werden dann mit Muster gefüllte Polygone, normale Polygone, Bézierkurven, Kuchen und weitere Funktionen beim Bilder-Zeichnen drankommen.

http://www.microsoft.com/downloads/details.aspx?...

Moderiert von user profile icontommie-lie: Link korrigiert

//Edit: Den einen oder anderen inhaltlichen Fehler korrigiert und den Headerlink aktualisiert
//Edit2: try-finally-Blocks eingebaut


Zuletzt bearbeitet von obbschtkuche am So 08.08.04 11:58, insgesamt 3-mal bearbeitet
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: So 08.08.04 10:00 
der ertelink geht nicht... kennst du noch einen andrenlink ?

_________________
MFG
Michael Springwald, "kann kein englisch...."
raziel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2453

Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
BeitragVerfasst: So 08.08.04 11:13 
Meinst Du den hier?
Da gäbs hier ne Alternative für...

raziel

_________________
JSXGraph
obbschtkuche
Gast
Erhaltene Danke: 1



BeitragVerfasst: So 08.08.04 11:29 
Ich lad den Header den ich benutze einfach nochmal bei mir hoch.
mimi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3458

Ubuntu, Win XP
Lazarus
BeitragVerfasst: So 08.08.04 13:31 
danke !!!

_________________
MFG
Michael Springwald, "kann kein englisch...."
jdv
Hält's aus hier
Beiträge: 1



BeitragVerfasst: Mo 04.04.05 15:47 
Ich habe versucht das Sample runtergeladen jedoch scheint dir URL nicht mehr zu stimmen.

_________________
DelphiCommunity
raziel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2453

Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
BeitragVerfasst: Mo 04.04.05 17:12 
Was meinst Du? Alle Links die ich im obigen Beitrag finden konnte funktionierten.

_________________
JSXGraph
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Mo 04.04.05 17:44 
Das meint er:

Microsoft hat folgendes geschrieben:

The download you requested is unavailable. If you continue to see this message when trying to access this download, you might try the "Search for a Download" area on the Download Center home page.


Und:

pages.infinit.net/smarth/gdiplus.html und www.progdigy.com/headers/ hat folgendes geschrieben:
Die Seite wurde nicht gefunden.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
raziel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2453

Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
BeitragVerfasst: Mo 04.04.05 20:07 
user profile iconGTA-Place hat folgendes geschrieben:
Das meint er:

Microsoft hat folgendes geschrieben:

The download you requested is unavailable. If you continue to see this message when trying to access this download, you might try the "Search for a Download" area on the Download Center home page.

Sucht ihr das hier?
www.microsoft.com/do...B&DisplayLang=en

user profile iconGTA-Place hat folgendes geschrieben:
Und:

pages.infinit.net/smarth/gdiplus.html und www.progdigy.com/headers/ hat folgendes geschrieben:
Die Seite wurde nicht gefunden.

Aber er hat das doch noch auf seinen eigenen Space hochgeladen:
odown.de.vu/GdiPlus.zip

_________________
JSXGraph
Ist die Frage beantwortet? Das Problem gelöst?

Dann klicke hier, um das Thema entsprechend zu markieren!