AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Erneutes Laden von Bitmaps: Speicherplatz freigeben
Thema durchsuchen
Ansicht
Themen-Optionen

Erneutes Laden von Bitmaps: Speicherplatz freigeben

Ein Thema von var-king · begonnen am 27. Sep 2011 · letzter Beitrag vom 28. Sep 2011
Antwort Antwort
var-king

Registriert seit: 8. Jan 2009
10 Beiträge
 
Turbo Delphi für Win32
 
#1

AW: Erneutes Laden von Bitmaps: Speicherplatz freigeben

  Alt 27. Sep 2011, 21:32
Gut, also jetzt mal systematisch.

Wenn ich zu einem anderen Bild "umschalte", geschieht Folgendes:

Delphi-Quellcode:
  bild.destroy;
  bild := Tbild.init;
  bild.open(pname);
Dabei ist bild.destroy der von mir definierte Destructor, ja, mit override:

Delphi-Quellcode:
destructor Tbild.destroy;
var i: integer;
begin
  current.Free;
  original.Free;
  for i := 1 to 10 do
    last[i].Free
end;
Der Constructor führt Folgendes durch:

Delphi-Quellcode:
constructor TBild.init;
var i: integer;
begin
  current := TBitMap.create;
  for i := 1 to 10 do
    last[i] := TBitMap.create;
  original := TBitMap.create;
  changed := false;
  showtext := true;
  setlength(textarray,0)
end;
Und schließlich hänge ich der Übersichtlichkeit halber auch noch die ganze open-Prozedur an:

Delphi-Quellcode:
procedure TBild.Open(pname: string);
var jpg: TJPEGImage;
    i: integer;
begin
  checksave;
  if lowercase(extractfileext(pname))='.jpgthen
  begin
    jpg := TJPEGImage.Create;
    jpg.loadfromfile(pname);
    original.assign(jpg);
  end else
  if lowercase(extractfileext(pname))='.bmpthen
    original.loadfromfile(pname);

  for i := 1 to 10 do
    last[i].Assign(original);
  name := pname;
  current.Assign(original);
  changed := false;
  application.title := Programmtitel+' | '+extractfilename(bild.name);
  with form1 do
  begin
    dateiliste(ExtractFilePath(bild.name), form1.datlist.Items);
    lb_groesse.Caption := inttostr(current.width)+'x'+inttostr(current.Height);
    lb_resolution.caption := 'Auflösung: 100% - '+inttostr(current.width)+'x'+inttostr(current.Height);
    form1.Caption := application.Title;
    lb_name.caption := extractfilename(bild.name)
  end;
  screenzoom;
  display
end;
Ja, es mag nicht besonders speicherschonend sein, direkt bei Open zehnmal das Original ins Array zu laden. Aber dies ist nun ziemlich fest im Programm verwurzelt und eigentlich kann dort auch nicht das Problem sein. Denn nach meiner Schreibweise müssten die ja auch komplett wieder freigegeben werden.

Trotzdem muss bei mir pro Bild 1% meines RAM dran glauben.

Jemand einen Tipp?
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.689 Beiträge
 
Delphi 2007 Enterprise
 
#2

AW: Erneutes Laden von Bitmaps: Speicherplatz freigeben

  Alt 27. Sep 2011, 22:38
Das wichtigste zuerst: Niemals Destroy() direkt aufrufen, immer Free() oder gleich FreeAndNil() - die Predigt haben wir hier öfter . Das wird in diesem Fall gut gehen, es gibt aber andere, in denen das nicht so geht, von daher besser sofort abgewöhnen.
Dann noch eine Stilsache: Der Konstruktor heisst Create(), nicht Init()! Von "Create" abweichende Namen sollte man nur für statische Methoden nehmen, die Factory-artig arbeiten, und selbst da sollte es immer noch irgendwie "Create" drin vorkommen.

Du schlabberst dir bei einem 10MP Bild damit aber auch gleich mal (10*1000000*4)/(1024*1024) ~= 380 MB Speicher voll, das ist ja schon mal was, und nicht die "feine Englische Art". In Open() wird "jpg" nie freigegeben, und ich bin mir fast sicher, dass TJpegImage intern eine dekomprimierte Version vorhält, ggf. noch weitere Metadaten, vor allem aber GDI Resourcen belegt, die schnell mal knapp werden können. Eventuell schafft das schon Abhilfe.
Zudem ist es mir schon ab und an passiert, dass mir FastMM Lecks angezeigt hat, wenn ich Arrays nicht mit Finalize() explizit und "ganz" platt gemacht habe, das ggf. also auch noch rein. Ich habe aber eher GDI Resourcen im Verdacht, nicht blos das RAM, auch wenn du das ziemlich mies behandelst
Was machen checksave, screenzoom und display? (Auch eher schlechte Namen übrigens, und sie riechen sehr deplatziert.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)

Geändert von Medium (27. Sep 2011 um 22:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.825 Beiträge
 
Delphi 12 Athens
 
#3

AW: Erneutes Laden von Bitmaps: Speicherplatz freigeben

  Alt 27. Sep 2011, 23:16
Und dann solltest du besser auf globale Variablen verzichten.

Wenn dein TBild das Form1 kennen soll, dann übergib es ihm im Constructor, über ein Property und speichere dieses in einem Feld,
oder als Parameter direkt an das Open, anstatt auf Form1 zuzugreifen.

Wobei ich alles ab application.title nicht in die Klasse reinmachen würde,
da man sich so eine untrennbare Verbindung einbaut.
Für sowas gibt es Callbacks/Events, wie z.B. das OnChange eines Edits ... man baut den seinen OnChange-Code ja auch nicht direkt in die TEdit-Klasse ein.
> wiederverwendbarer Code

PS: Du nutzt with Form1 do und greifst darin nochmal auf Form1 zu, obwohl du dich schon in dessen Scope/Gültigkeitsbereich befindest?
Ist nicht schlimm, aber "unschön". (abgesehn davon daß man auf sowas besser nicht direkt zugreifen sollte)



Zu der Bezeichnung "Init":
Diese ist auch noch syntaktisch falsch, denn dort erstellst und initialisierst du das Objekt, anstatt es nur zu initialisieren.

Abgesehn davon, daß sich Create als Constructor etabliert hat und jeder weiß was dieses macht, wenn man nur den Namen ließt ... das ist bei init nicht der Fall.
> selbsterklärender Code
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (27. Sep 2011 um 23:21 Uhr)
  Mit Zitat antworten Zitat
var-king

Registriert seit: 8. Jan 2009
10 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Erneutes Laden von Bitmaps: Speicherplatz freigeben

  Alt 28. Sep 2011, 14:15
Das Lustige ist, dass wir Init tatsächlich damals so im Informatikunterricht gelernt haben...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.825 Beiträge
 
Delphi 12 Athens
 
#5

AW: Erneutes Laden von Bitmaps: Speicherplatz freigeben

  Alt 28. Sep 2011, 14:56
Was viele Leherer leheren , ist halt nicht das Wahre.

(auch wenn es einige erfreuliche AAusnahmen an Lehrern gibt)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:16 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