Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bitmap als Zeiger - Ich versteh es nicht ! (https://www.delphipraxis.net/59323-bitmap-als-zeiger-ich-versteh-es-nicht.html)

meisteralex 20. Dez 2005 17:36


Bitmap als Zeiger - Ich versteh es nicht !
 
Delphi-Quellcode:
function bitblt_encode(bild1, bild2:tbitmap):tbitmap;
var
tempbild1,tempbild2:tbitmap;
begin
  tempbild1 := tbitmap.create;
  tempbild2 := tbitmap.Create;
  tempbild1.Assign(bild1);
  tempbild2.Assign(bild2);
                  //hier wird image 1 geändern wenn ide orginalrefferenze übergeben wird !!!
  bitblt(result.Canvas.Handle ,0,0,tempbild1.Width,tempbild1.Height,tempbild1.Canvas.Handle,0,0,srccopy);
  bitblt(result.Canvas.Handle ,0,0,tempbild2.Width,tempbild2.Height,tempbild2.Canvas.Handle,0,0,srcinvert);

  tempbild1.free;
  tempbild2.Free;

end;
habe die oben stehende funktion geschreiben und wende sie wie folgt an:

Delphi-Quellcode:
  bit1 := tbitmap.Create;
  bit2:= tbitmap.Create ;
  bit1.LoadFromFile('C:\bild1.bmp');
  bit2.LoadFromFile('c:\bild2.bmp');
  diffimage := tbitmap.Create;
  diffimage2 := tbitmap.Create;

  image1.Picture.Bitmap.Assign(bit1);
  image2.Picture.Bitmap.Assign(bit2);

  diffimage.Assign(bitblt_encode(bit1,bit2));

  image1.Picture.Bitmap.Assign(bit1);
  image2.Picture.Bitmap.Assign(bit2);
mein problem ist, dass die funktion bit2 ändert .
Ok, das mit den Zeiger versteh ich ja, dass ich der Funktion einen Zeiger auf das BitmapObjekt übergeben, deshalb weiße ich in der Funktion ja dem tempbild2 mit tempbild2.assign(bit2) den inhalt zu und arbeite damit weiter. warum ändert sich also trotzdem bit2 nach dem durchlauf der funktion ???
kann mir jemand erklären wie ich die funkton schreiben müsste, damit sie in keinster weise die ihr übergebenen objekte verändert ???

Nuclear-Ping 20. Dez 2005 17:42

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Öhm, keine Ahnung, aber mal was anderes als Allgemeintip: Du solltest in der Funktion erstmal Result als Instanz von TBitmap erzeugen.

Weiterhin ist es nicht empfehlenswert, Funktionen, die eine Instanz zurückliefern, direkt zu übergeben, sondern diese erst einmal in einer Arbeitsvariablen zwischenzuspeichern, damit man diese nach Benutzung wieder freigeben kann. Das ist insofern sinnvoll, als das anderweitig ein Leak entsteht.

meisteralex 20. Dez 2005 17:58

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
hab ich doch gemacht tempbild ist doch meine arbeitsvariable

Nuclear-Ping 20. Dez 2005 18:05

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Und warum arbeitest du dann mit Result.Canvas.Handle in BitBlt? Es existiert doch garkeine Instanz von Result. Wundert mich auch, dass du keine AV kriegst.

Khabarakh 20. Dez 2005 18:06

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Zitat:

Zitat von meisteralex
hab ich doch gemacht tempbild ist doch meine arbeitsvariable

Das steht so aber nicht im obigen Code.
Delphi-Quellcode:
//hier wird image 1 geändern wenn ide orginalrefferenze übergeben wird !!!
  bitblt(result.Canvas.Handle ,0,0,tempbild1.Width,tempbild1.Height,tempbild1.Canvas.Handle,0,0,srccopy);
Das kann einfach nicht sein. Aber die Routine ist sowieso komplett falsch, solange du nicht wie schon gesagt Result auch instanziierst.

meisteralex 20. Dez 2005 20:30

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
hmm, wenn ich jetzt mit result := tbitmpa.create(); result erzeuge, wo muss ich es dann mit result.free wieder freigeben ?

Khabarakh 20. Dez 2005 20:34

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Zitat:

Zitat von meisteralex
hmm, wenn ich jetzt mit result := tbitmpa.create(); result erzeuge, wo muss ich es dann mit result.free wieder freigeben ?

Gar nicht. Da du die Referenz ja nach außen weitergibst, muss sie auch dort und nicht in der Prozedur freigegeben werden. Genau deshalb solltest du eben das Ergebnis in einer Variablen speichern.

meisteralex 20. Dez 2005 20:52

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
wie denn ?
wenn ich mit

variable.assign(funktion());

arbeite, kopiere ich ja quasi nur das result , oder ?
wie weise ich denn variable die adresse von result zu ?

Khabarakh 20. Dez 2005 21:02

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Delphi-Quellcode:
BitVariable := bitblt_encode(...);
:wink:
Wie gesagt, Objektvariablen sind nichts anderes als Zeiger.

meisteralex 21. Dez 2005 07:48

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
hmm dann müsste ich meinem zeiger BitVariable ja eigentlich gar keine
neue instanz mit bitbariable := tbitmap.create; zuweisen oder ?
weil er soll ja eigentlich nur ne adresse aufnehmend!

wenn ich jetzt mit bitvariable:= bitblt_encode(...); dem zeiger bitvariable die adresse des results von bitblt_encode zuweise, wie ist es dann, wenn ich die funktion bitblt_encode wieder gebrauche ??
Die Rückgabewerte bei verschiedenen Aufrufen sollten doch dann getrennte Instanzen sein oder ?

jfheins 21. Dez 2005 09:05

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Kleines Beispiel:
Delphi-Quellcode:
function MyFunc (AValue: String): TBitmap;
var
  MyVar: Boolean;
begin

  //Etwas machen

  Result := TBitmap.Create;

  Result.Machwas;

end;

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

var
  TempBmp, Bmp1, Bmp2, Bmp3, Bmp4: TBitmap;
begin
  Bmp1:= TBitmap.Create;
  Bmp2:= TBitmap.Create;
  Bmp1.LoadFromFile('C:\bild1.bmp');
  Bmp2.LoadFromFile('C:\bild2.bmp');

  TempBmp := MyFunc ('Ein Bitmap bitte');

  Bmp3 := TempBmp; // Addresse zugewiesen - Bmp3 und TempBmp zeigen auf dasselbe Bitmap

  Bmp4 := TBitmap.Create;
  Bmp4.Assign (TempBmp); // Bitmap Kopiert

  // Hier zeigen TempBmp und Bmp3 auf das zurückgegebene Bitmap und Bmp4 zeigt auf eine Kopie dessen.

  TempBmp := MyFunc ('Ein anderes Bitmap bitte'); // Kein Leak, wel Addresse noch in Bmp3
  // Bmp3 := nil; // Leak
  FreeAndNil (Bmp3);
Ich hoffe, ich konnte dir helfen ;)

xaromz 21. Dez 2005 09:40

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
Hallo,
Zitat:

Zitat von jfheins
Kleines Beispiel:
Delphi-Quellcode:
...
Bmp4.Assign (TempBmp); // Bitmap Kopiert
...

Das wird so nicht funktionieren, wenn Du Bmp4 nicht initialisierst.

Gruß
xaromz

jfheins 21. Dez 2005 09:42

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
:oops: Das sollte nicht passieren ...

Cicaro 22. Dez 2005 10:34

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
@meisteralex:
Es ist schon richtig gesagt worden: es ist nicht sehr elegant eine Instanz als Rückgabewert einer Funktion zu verwenden.

Erstell doch einfach außerhalb der Funktion/Prozedur alle notwendigen Bitmaps, dann übergib' sie der Funktion/Prozedur als Zeiger.
Delphi-Quellcode:
procedure BmpEncode(Bitmap1,Bitmap2,Bitmap3:TBitmap);
begin
  // macht was mit Bitmap1 und Bitmap2 und legt das Ergebnis in Bitmap3
end;
So sollte es ohne Probleme funktionieren.

Eleganter finde ich diese Prozedur, wenn man ScanLine nicht braucht und stattdessen mit den relativ schnellen API-Funktionen arbeitet:
Delphi-Quellcode:
procedure EncodeDCs(SrcDc1,SrcDC2,DestDC:HDC);
begin
  // macht was mit SrcDC1 und SrcDC2 und legt das Ergebnis in DestDC
end;

// Aufruf:
EncodeDCs(Bitmap1.Canvas.Handle,Bitmap2.Canvas.Handle,Bitmap3.Canvas.Handle);
Sinnvoll bei sprachübergreifender Programmierung.

meisteralex 22. Dez 2005 14:56

Re: Bitmap als Zeiger - Ich versteh es nicht !
 
jo hab das prinzip jetzt verstanden -> dank euch, also vielen dank


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:41 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz