Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   FreePascal Bitmap mehrmals neu aus Datei laden (https://www.delphipraxis.net/187396-bitmap-mehrmals-neu-aus-datei-laden.html)

TForm1 25. Nov 2015 17:22

Bitmap mehrmals neu aus Datei laden
 
Hallo zusammen,

ich habe folgendes Problem und zwar lade ich eine Bitmap zunächst ganz normal mit .LoadFromFile() und möchte sie danach nochmal von einem anderen File laden.
Delphi-Quellcode:
procedure TMainController.loadKeyedFrame;
begin
  FActKeyedFrame.Clear;
  if not (FileExists(MainDirectoryPath+'keyed'+intToStr(FActFrameindex)+'.bmp')) then
  begin
    showmessage('Keyed Frames bitmap files existieren nicht');
    exit;
  end;
  FActKeyedFrame.loadFromFile(MainDirectoryPath+'keyed'+intToStr(FActFrameindex)+'.bmp');
end;
Problem ist jetzt, dass das Programm sich immer bei FActKeyedFrame.Clear aufhängt, bzw der Debugger eine falsche Speicherzugriff- Exception schmeißt. Wenn ich mit Breakpoint Schritt für Schritt durchgehe meldet mir der Debugger: Cannot find bounds of current function...
Wisst ihr warum dieser Fehler auftritt, bzw wie man das lösen kann?

Die Bitmap FActKeyedFrame ist bereits instanziert und wurde zu Beginn von einer anderen Bitmap geladen also
Delphi-Quellcode:
FActKeyedFrame:=BufferBitmap;
Könnte da der Fehler liegen?

Danke schonmal!

Perlsau 25. Nov 2015 18:07

AW: Bitmap mehrmals neu aus Datei laden
 
Zitat:

Zitat von TForm1 (Beitrag 1322499)
Problem ist jetzt, dass das Programm sich immer bei FActKeyedFrame.Clear aufhängt, bzw der Debugger eine falsche Speicherzugriff- Exception schmeißt.

FActKeyedFrame ist ein TBitmap?
Was genau ist "eine falsche Speicherzugriff- Exception"?

An deinem Code kann ich keinen Fehler finden, zumal der Fehler ja bereits in der ersten Zeile entsteht, wie du schreibst. Bei Lazarus löscht TBitmap.Clear die Grafik und hinterläßt eine leere Grafik (TBitmap.Clear gibt's bei Delphi nicht, nur bei FMX). Was du sonst noch außerhalb dieser offenbarten Procedure machst, entzieht sich meiner Kenntnis. Der Fehler muß also irgendwo anders bereits passieren ... vermutlich löschst du irgendwo die Bitmap-Instanz, auf die du dann wieder zuzugreifen versuchst.

Bjoerk 25. Nov 2015 18:28

AW: Bitmap mehrmals neu aus Datei laden
 
Um das Bild zu löschen kannst du auch Bitmap := nil schreiben.

Sir Rufo 25. Nov 2015 18:37

AW: Bitmap mehrmals neu aus Datei laden
 
Zitat:

Zitat von TForm1 (Beitrag 1322499)
Die Bitmap FActKeyedFrame ist bereits instanziert und wurde zu Beginn von einer anderen Bitmap geladen also
Delphi-Quellcode:
FActKeyedFrame:=BufferBitmap;
Könnte da der Fehler liegen?

Ja, denn so schickst du die Instanz ins MemLeak-Nirwana.
Delphi-Quellcode:
// Instanz erzeugen
FActKeyedFrame := TBitmap.Create;
// Instanz zuweisen
FActKeyedFrame := BufferBitmap;
// ei jo, die eben erzeugte Instanz dümpelt jetzt im Speicher rum ... und keiner weiß wo
...
// BufferBitmap freigeben, die brauche ich ja nicht mehr, oder?
FreeAndNil( BufferBitmap );
// rumms
FActKeyedFrame.LoadFromFile(...);
darum
Delphi-Quellcode:
// Instanz erzeugen
FActKeyedFrame := TBitmap.Create;
// Instanz-Werte zuweisen
FActKeyedFrame.Assign( BufferBitmap );
Zitat:

Zitat von Bjoerk (Beitrag 1322505)
Um das Bild zu löschen kannst du auch Bitmap := nil schreiben.

Nein, einfach so geht das nicht. Das geht nur, wenn es sich bei
Delphi-Quellcode:
Bitmap
um eine Eigenschaft handelt und der Setter der Eigenschaft diese
Delphi-Quellcode:
nil
-Zuweisung entsprechend behandelt.
Delphi-Quellcode:
procedure TFoo.SetBitmap( const Value : TBitmap );
begin
  if Assigned( Value ) then
    FBitmap.Assign( Value )
  else
    FBitmap.Clear;
end;

TForm1 25. Nov 2015 18:46

AW: Bitmap mehrmals neu aus Datei laden
 
Genau FActKeyedFrame ist ein TBitmap.
Mit falscher Speicherzugriff- Exception meine ich External: EXC_BAD_ACCESS

Die BufferBitmap, die ich zu Anfang FActKeyedFrame zuweise, wird nach der Zuweisung tatsächlich gelöscht, aber das sollte doch keine Auswirkung auf FActKeyedFrame haben schließlich ist das eine eigene Instanz?

Bevor ich die neue Bitmap lade speicher ich die alte über FActKeyedFrame.SaveToFile() ansonsten passiert eigentlich nichts mit dem Objekt, außer ein paar mal eine Abfrage von FActKeyedFrame.Width und .Height...

@SirRufo:

FActKeyedFrame habe ich vorher instanziert und dann zugewiesen, muss das also mit Assign() erfolgen?

Sir Rufo 25. Nov 2015 19:01

AW: Bitmap mehrmals neu aus Datei laden
 
Zitat:

Zitat von TForm1 (Beitrag 1322507)
FActKeyedFrame habe ich vorher instanziert und dann zugewiesen, muss das also mit Assign() erfolgen?

Nur zum Verständnis:
Delphi-Quellcode:
// Instanz erzeugen
// Referenz zur Instanz der Variable FActKeyedFrame zuweisen
FActKeyedFrame := TBitmap.Create;

// Referenz zur Instanz BufferBitmap der Variable FActKeyedFrame zuweisen
FActKeyedFrame := BufferBitmap;

// BufferBitmap wird nicht mehr benötigt
BufferBitmap.Free;

// Wir machen was mit unserer Bitmap
FActKeyedFrame.LoadFromFile( ... ); // öh .... es rummst
Oder im realen Leben:
  • Ich baue ein Haus und die Adresse schreibe ich auf einen Zettel
  • Ich überschreibe den Zettel mit der Adresse von Peter
  • Peter reißt sein Haus ab
  • Ich ziehe in das Haus ein, dessen Adresse ich auf meinem Zetttel stehen habe
Frage: Ich welches Haus ziehe ich jetzt konkret ein?

Richtig! In gar kein Haus, denn wir haben die Adresse von Peters Haus und da gibt es kein Haus mehr!

Aber wie denn dann richtig?

Wie machen wir das im realen Leben?
  • Ich baue ein Haus und die Adresse schreibe ich auf einen Zettel
  • Ich baue mein Haus um, so dass es wie das Haus von Peter aussieht
  • Peter reißt sein Haus ab
  • Ich ziehe in das Haus ein, dessen Adresse ich auf meinem Zetttel stehen habe
und dieses umbauen, dass es so aussieht wie geht mit einem
Delphi-Quellcode:
TBitmap
so
Delphi-Quellcode:
// Instanz erzeugen
// Referenz zur Instanz der Variable FActKeyedFrame zuweisen
FActKeyedFrame := TBitmap.Create;

// Referenz zur Instanz BufferBitmap der Variable FActKeyedFrame zuweisen
FActKeyedFrame.Assign( BufferBitmap );

// BufferBitmap wird nicht mehr benötigt
BufferBitmap.Free;

// Wir machen was mit unserer Bitmap
FActKeyedFrame.LoadFromFile( ... ); // öh .... es rummst NICHT mehr

TForm1 25. Nov 2015 19:31

AW: Bitmap mehrmals neu aus Datei laden
 
Ah Super ja genau das Verständnis wie eine solche Zuweisung funktioniert, fehlte mir noch.

Jetzt klappts vielen Dank!:thumb::-D

Bjoerk 25. Nov 2015 21:01

AW: Bitmap mehrmals neu aus Datei laden
 
Zitat:

.. Nein, einfach so geht das nicht. Das geht nur, wenn es sich bei
Delphi-Quellcode:
Bitmap
um eine Eigenschaft handelt und der Setter der Eigenschaft diese
Delphi-Quellcode:
nil
-Zuweisung entsprechend behandelt ..
A ja, stimmt. Mit TPicture verwechsel. Sorry. :oops:

Perlsau 26. Nov 2015 04:53

AW: Bitmap mehrmals neu aus Datei laden
 
Oder – der Vollständigkeit halber – anders ausgedrückt:
  • Mit Assign erhältst du eine eigenständige Kopie; das Bitmap wird physisch kopiert in einen eigenen Speicherbereich.
  • Mit der Zuweisung via := wird lediglich die Speicheradresse, an der das Bitmap beginnt, zugewiesen. bzw. kopiert. Du hast danach also zwei Variablen (Zeiger), die auf dasselbe Bitmap zeigen. Löschst du jetzt den Speicherbereich, zeigt auch der zweite Zeiger ins Daten-Nirwana.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:12 Uhr.

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