Entwickler-Ecke

Multimedia / Grafik - Einfache Bitmap verzerren - Trapez -> Quadrat


soong101 - Sa 19.04.08 16:27
Titel: Einfache Bitmap verzerren - Trapez -> Quadrat
Hallo,

ich möchte gerne eine Prozedur schreiben, die a) eine Bitmap nimmt (aus der Zwischenablage), b) diese manipuliert und dann c) in eine Datei speichert.
a) und c) werd ich wohl hinkriegen, aber b) macht mir Sorgen.
Ich habe mal eine Beispielbitmap angehängt. Das ist eine Karte aus einem 3D-Spiel. Es ist eine Draufsicht von schräg oben. Die gelbe Umrandung markiert den Spielbereich. Jetzt will ich das Bild so verzerren, dass die gelbe Umrandung zu einem Quadrat wird und die Bitmap nur noch den Inhalt des Spielbereichs anzeigt. Damit erzeuge ich aus einer Fast-Draufsicht eine Draufsicht.
Wie kann ich das machen? Geht das mit Delphi-Bordmitteln oder brauch ich da noch was zusätzlich?


winx - Mo 21.04.08 16:31

sorry kann dir da leider nicht helfen, aber ich interessiere mich auch für das Problem :-)


soong101 - So 27.04.08 18:59

GR32_Transforms vom Graphics32-Projekt scheint mächtig genug, um die Aufgabe zu lösen. Damit werde ich es versuchen. Obs geklappt hat, trag ich dann nach.


delfiphan - So 27.04.08 22:40

Die Lösung findest du hier: http://www.delphi-forum.de/viewtopic.php?t=82767

Die Umkehrfunktion von TProjectiveTransformation von graphics32 macht wohl mehr oder weniger dasselbe.


ub60 - Mo 28.04.08 00:25

Ich hab jetzt mal ne Variante zu Fuß geschrieben (nur für symmetrische Trapezverzerrung).
Im Image1 muss das Ausgangsbild stehen (BMP).


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:
procedure TForm1.BitBtn1Click(Sender: TObject);
var dxOben, dxUnten, links, x, y, Breite, Hoehe : Integer;
    Farbe : TColor;
    Faktor1, Faktor2 : Double;
begin
  Breite:=Image1.Width-1;
  Hoehe:=Image1.Height-1;
  dxOben:=26;   // Abstand von links und rechts oben
  dxUnten:=10;  // Abstand von links und rechts unten
  Faktor1:=(dxOben-dxUnten)/Hoehe;
  with Image1.Canvas do   // 2 rote Linien zur Anzeige
    begin                 // der Grenze
      Pen.Color:=clRed;
      MoveTo(dxOben,0);
      LineTo(dxUnten,Hoehe);
      MoveTo(Breite-dxOben,0);
      LineTo(Breite-dxUnten,Hoehe);
    end;
  for y:=0 to Hoehe do
    for x:=0 to Breite do
      begin
        links:=dxOben-Round(Faktor1*y);
        Faktor2:=(Breite-2*links)/Breite;
        Farbe:=Image1.Canvas.Pixels[links+Round(x*Faktor2),y];
        Image2.Canvas.Pixels[x,y]:=Farbe;
      end;
end;

Ein Beispielbild ist im Anhang. Ich hoffe, das war so die gewünscht Verzerrung.

ub60


soong101 - Mi 30.04.08 19:34

Jap, ich danke dir!