Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Fehler beim Maximieren einer Form mit einem Image


klezmor - Di 06.03.07 19:08
Titel: Fehler beim Maximieren einer Form mit einem Image
wenn ich bei meiner Form windowstate auf wsmaximised setzte, ist diese schräg nach untenversetzt.
Zuvor habe ich in der funktion mit dieser funktion:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.RefreshBackground;
var i:byte;
begin
 Image1.Canvas.Brush.Color:=clBlack;
 image1.Canvas.Pen.Width:=marginwidth;
 image1.Canvas.Pen.Color:=margincol;                   
 Image1.Canvas.Rectangle(0,0,Image1.Width-150,Image1.Height);
 image1.Canvas.Rectangle(image1.Width-150,0,image1.Width,image1.height);
end;

hineingezeichnet, diese blauen rechtecke sind verzogen. Auch die penwidth ist auf einmal vielgrößer als sonst, ist die Form nicht maximiert funktioniert es wunderbar.


klezmor - Di 06.03.07 20:07

Die Routine sieht jetzt so aus.
wenn backgroundimage <>'' dann wird trotzdem kein bild angezeigt.
Ich vermute dies liegt daran, dass die bitmap, welche ich lade, nicht so groß ist wie das image ist. So dass es so zu einem speicher konflikt kommt. Könnte natürlich auch an was anderem liegen.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.RefreshBackground;
begin

 image1.Picture.Bitmap.Width:=image1.Width;
 image1.Picture.Bitmap.Height:=image1.Height;
 if backgroundimage<>'' then
 begin
  image1.Picture.bitmap.LoadFromFile(backgroundimage);
  Image1.Canvas.Draw(0,0,image1.Picture.Bitmap);
 end
 else
 begin
  Image1.Picture.Bitmap.Canvas.Brush.Color:=clBlack;
  Image1.Picture.Bitmap.Canvas.Rectangle(0,0,Image1.Width-150,Image1.Height);
 end;
 image1.Picture.Bitmap.Canvas.Pen.Width:=marginwidth;
 image1.Picture.Bitmap.Canvas.Pen.Color:=margincol;
 image1.Picture.Bitmap.Canvas.Rectangle(image1.Width-150,0,image1.Width,image1.height);

end;


klezmor - Mi 07.03.07 00:11

hab schon gesucht, aber nichts gefudnen, ich bräuchte eine routine, welche ein bild der größe eines Images anpasst.


klezmor - Mi 07.03.07 00:39

Also nochmal zur Fragestellung ich habe eine imagekomponente, auf welche ich etwas zeichnen möchte, das bild soll sich dabei automatisch der form größe anpassen.
Eigentlich image.align:=client, das funzt aber nicht.


klezmor - Mi 07.03.07 14:41

Ok das Problem hat sich nochmal ein wenig verändert.
In meinem Spiel will ich auf ein image.canvas bzw. image.picture.bitmap.canvas zeichnen.
1.Ist das eigentlich gleichschnell?

Der Code für das zeichnen ist unten aufgeführt. Die Eigenschaften der form auf welcher das image liegt sind: windowstate:maximized und image.align:=client;
Es soll also auf dem ganzen Bildschirm gezeichnet werden.

Folgende Prozedur soll, wenn backgroundimage<>'' ist ein hintergrundbild laden und dieses in die Bitmap zeichnen.Hierbei soll das Bitmap, wenn es kleiner ist wie das image, dessen größe angepasst werden.

Trifft dies nicht zu, so soll einfach ein schwarzer hintergrund erstellt werden und blau umrandet werden.

Mein bisheriger Code ist folgender:

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:
procedure TForm1.RefreshBackground;
var i,Bmp:byte;
begin

 if backgroundimage<>'' then
 begin
  image1.Picture.Bitmap.LoadFromFile(backgroundimage);
  image1.Picture.Bitmap.Canvas.StretchDraw(image1.Picture.Bitmap.Canvas.ClipRect,image1.Picture.bitmap);
  image1.Picture.Bitmap.PixelFormat:= pf24Bit;
  // Image1.Canvas.Draw(0,0,image1.Picture.Bitmap);
  //Form1.Image1.picture.bitmap.canvas.StretchDraw(Rect(0,0,image1.Picture.Bitmap.Width div 7,image1.Picture.Bitmap.Height div 7),image1.Picture.Bitmap);
 end
 else
 begin
  Image1.Picture.Bitmap.Canvas.Brush.Color:=clBlack;
  Image1.Picture.Bitmap.Canvas.Rectangle(0,0,Image1.Width-150,Image1.Height);
 end;

 image1.Picture.Bitmap.Width:=image1.Width;
 image1.Picture.Bitmap.Height:=image1.Height;
 image1.Picture.Bitmap.Canvas.Pen.Width:=marginwidth;
 image1.Picture.Bitmap.Canvas.Pen.Color:=margincol;
 image1.Picture.Bitmap.Canvas.Rectangle(image1.Width-150,0,image1.Width,image1.height);

 application.ProcessMessages;
end;


Allerdings funktioniert der code nicht, das bild wird nicht auf imagesize vergrößert


klezmor - Do 08.03.07 22:15

Hat keiner eine Ahnung wie man sowas realisieren könnte?


klezmor - Fr 09.03.07 22:39

Wird der Thread möglicherweise im Forum gar nicht angezeigt?


Dunkel - Fr 09.03.07 23:23

user profile iconklezmor hat folgendes geschrieben:
Wird der Thread möglicherweise im Forum gar nicht angezeigt?

Also ich kann ihn lesen (und finde Deinen Monolog schon irgendwie... seltsam :wink: ).

Zum Deinem Problem:
Versuch mal TImage.Stretch auf True zu setzen, wenn das Bild proportional größer werden soll (also ohne Verzerrung in der X-/Y-Achse) sollte noch TImage.Proportional auf True gesetzt werden.


Blackheart666 - Fr 09.03.07 23:26

Frust ? Vieleicht hilft es wenn Du mal das Projekt mit ranhängst.
Ehrlich gesagt versteh Ich nur Bahnhof, und hab es schon des öfteren gelesen.
"Das wird Dir jetzt nicht unbedingt weiter helfen, aber bringt den Thread wieder nach Oben" :wink:


klezmor - Fr 09.03.07 23:38

Ich will jetzt nicht beleidigen, aber hätte eigentlich gedacht, wenn man sich den Code ansieht, dass dann eigentlich klar ist um was es in meinem Programm geht.

user profile iconDunkel hat folgendes geschrieben:

Also ich kann ihn lesen (und finde Deinen Monolog schon irgendwie... seltsam :wink: ).


Also Spass hat mir der Monolog eigentlich keinen gemacht, wäre auch nciht nötig gewesen, wenn sich jemand mal ein wenig früher dem Problem gewidmet hätte.

user profile iconDunkel hat folgendes geschrieben:

Zum Deinem Problem:
Versuch mal TImage.Stretch auf True zu setzen, wenn das Bild proportional größer werden soll (also ohne Verzerrung in der X-/Y-Achse) sollte noch TImage.Proportional auf True gesetzt werden.


also es geht nicht direkt um die image komponente( diese verwende ich nur, damit bei einem minimieren nicht alles verlorgen geht), sondern um Image1.picture.bitmap.canvas, In dieses Canvas will ich ein Bild laden, welches dann so vergrößert wird, dass es so groß wie mein Image1.


Dunkel - Sa 10.03.07 00:12

user profile iconklezmor hat folgendes geschrieben:
Ich will jetzt nicht beleidigen, aber hätte eigentlich gedacht, wenn man sich den Code ansieht, dass dann eigentlich klar ist um was es in meinem Programm geht.

user profile iconDunkel hat folgendes geschrieben:

Also ich kann ihn lesen (und finde Deinen Monolog schon irgendwie... seltsam :wink: ).


Also Spass hat mir der Monolog eigentlich keinen gemacht, wäre auch nciht nötig gewesen, wenn sich jemand mal ein wenig früher dem Problem gewidmet hätte.

OT: Das Forum ist kein Hilfe-auf-Abruf-Automat! Wenn niemand antwortet, dann antwortet halt niemand!
Schiebepostings sind unter aller Sau (ich bin eh dafür, die 24h-Begrenzung auf eine 24D-Begrenzung zu erweitern)!


user profile iconklezmor hat folgendes geschrieben:

also es geht nicht direkt um die image komponente( diese verwende ich nur, damit bei einem minimieren nicht alles verlorgen geht), sondern um Image1.picture.bitmap.canvas, In dieses Canvas will ich ein Bild laden, welches dann so vergrößert wird, dass es so groß wie mein Image1.

Ich befürchte schon fast, dass Du das Resizen selber coden mußt; zumindest ist mir nicht bekannt, wie man in einem Canvas ein Bild vergrößern kann.


Lannes - Sa 10.03.07 22:09

Hallo,

ich vermute das Dir das Stichwort OffScreenBitmap weiterhilft :wink:


klezmor - Mo 12.03.07 19:06

kann mir vielleicht mal jemand die Rückmeldung geben, ob er das Problem überhaupt verstanden hat. Habe das Gefühl, dass keiner weiß was ich meine.


klezmor - Mo 12.03.07 20:22

@ Lannes, das hat mich gar nicht weitergebracht, habe auch mal diesen DiesenLink [http://www.michael-puff.de/Developer/Artikel/2003_2005/WieWindowsFunktioniert.shtml]im zusammenhang gefunden, welcher mir genauso wenig gezeigt hat.


Lannes - Di 13.03.07 11:25

Hallo,

hast Du auch mal versucht den Code, ganz am Ende des Artikels, an Deine Wünsche anzupassen?

In FormCreate erzeugt man ein OffScreenBitmap(TBitmap) in das mit Bitmap.LoadfromFile das Bild geladen wird. In FormDestroy das TBitmap wieder freigeben.

Dein Image durch eine Paintbox ersetzen, denn die PaintBox stellt Dir das Ereignis OnPaint zur Verfügung. PaintBoxOnPaint wird u.A. aufgerufen wenn die Formgröße verändert wird, da PaintBox.Align auf alClient eingestellt ist.

In PaintBoxOnPaint wird dann jedesmal das Bild neu gezeichnet, z.B. mit PaintBox.Canvas.StretchDraw oder auch mit StretchBlt.
dsdt: BitBlt/StretchBlt [http://www.dsdt.info/tutorials/bitmap/?page=8&x=3&y=4]


klezmor - Di 13.03.07 17:30

Ich verwende keine Paintbox sondern ein Image, sonst sind meine striche weg, welche ich mit canvas zeichne. Glaub du meinst was anderes kann das sein?


Lannes - Di 13.03.07 20:42

Hallo,

teste das mal, ich glaube das ich das richtige meine:

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:
39:
40:
41:
42:
43:
44:
  public
    bmp : TBitmap;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
const  marginwidth = 5;
       margincol = clBlue;
       backgroundimage = 'c:\temp\EinBild.bmp';
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  bmp := TBitmap.Create;
  bmp.Height := 10;
  bmp.Width := 10;
  PaintBox1.Canvas.Brush.Color := margincol;
  if backgroundimage <> '' then
    begin
    bmp.LoadFromFile(backgroundimage);
    end
    else
      begin
      bmp.Canvas.Brush.Color := clBlack;
      bmp.Canvas.FillRect(bmp.Canvas.ClipRect);
      end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  bmp.Free;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.FillRect(PaintBox1.Canvas.ClipRect);
  PaintBox1.Canvas.StretchDraw(Rect(marginwidth,
                                    marginwidth,
                                    PaintBox1.Width-marginwidth,
                                    PaintBox1.Height-marginwidth),bmp);
end;


klezmor - Do 15.03.07 00:15

ok werde es mal ausprobieren.