Jak wrzucic do pamieci kilkaset bitmap?

0

Witam!

Mam następujący problem:
Muszę trzymać w pamięci, równocześnie kilkaset bitmap. Bitmapy muszą być dostępne bardzo szybko dlatego nie wchodzi w rachubę ładowanie ich z dysku - one muszą być w pamięci. Nie mogę trzymac tego jako klasyczne obiekty TBitmap bo bardzo szybko zobacze komunikat Out of Resources.

Jak to zrobić???

Mój pomysł jest w zarysie taki:

  1. Wczytuje bitmape jako TBitmap
  2. Likwiduje TBitmap jako obiekt ale tak żeby nie zwolnić pamięci w której znajdują się dane obiektu.
  3. Zapamietuje w tablicy wskaznik do zlikwidowanego obiektu.
  4. W odpowiednim momenci gdy potrzebuje danej bitmapy tworze obiekt TBitmap ale tak żeby wskazywał mi te dane które znajdują się w pamięci

To jest schemat mojego pomyslu ale nie wiem za bardzo jak to wykonac. Tzn w jaki sposób zniszczyć obiekt bez zwolnienia pamięci w której dane się znajdują?
Jak potem utworzyć nowy obiekt żeby wykorzystywał te dane?

Tomek

0

Dziwny jest twój pomysł. Przecież jak zwolnisz obiekt, to ta część pamięci w której on był może zostać zamazana przez cokolwiek innego.

0

No właśnie wiem.

I dlatego napisałem że nie wiem jak to zrobić. Taki jest tylko ogólny zarys rozwiązania problemu.

Pytanie jest w jaki sposób sprawić, żeby obiekt z jednej strony zwolnić ale z drugiej zeby nie zwolnić pamięci i żeby nic mi tego nie zamazało. Czy to jest w ogóle możliwe?

Tomek

0

Stwórz sobie rekord taki:

type
 TKolorki=array[0..szerokosc, 0..wysokosc] of TColor;

To ci będzie mniej zajmować niż TBitmap.

[dopisane]
Czyli chcesz oszukać system? :)

[dopisane2]
Użyj wskaźników

0

Mozna zrobic to tak:


var z : array [0..1000] of ^TBitmap;
    i: integer;
begin
  for i:=0 to 1000 do
  begin
    New(z[i]);
    z[i]^ := TBitmap.create();
    z[i]^.LoadFromFile('c:\z.bmp');
  end;

gdzie z zadeklarowane globalnie aby zawsze bylo dostepne. dostep do tego jest poprzez z[i]. zalezy jeszcze czy te bitmapy sa duze moze warto je jeszcze w locie konwertowac na jpg. jak cos to kontakt na gg.</delphi>

0

I to będzie działało w każdym systemie, także w Win98?

Przetestowałem sobie na swoim komputerze (1Gb RAM, WinXp)
Do około 4500 Bitmap działa dobrze ale potem dostaję błąd:

"Code 87 Parametr jest niepoprawny."

Dlaczego?

I jeszcze jedno

Jak się dobrze zastanowić to właściwie potrzebuje nawet nie kilkaset bitmap ale 2000 - 3000.

0

nie wiem w czym problem. zaladowalem sobie 5000 bitmap (kazda po 50k) i nie mialem zadnego bledu. to predzej wina wczytywanej bitmapy - sprawdz czy dobrze podajesz nazwy bitmap i czy ma odpowedni format. jak duze te btmapy wczytujesz?

mam WINXP i 512 ramu

0

I jeszcze jedna sprawa

Co do tablicy to odpada. Te bitmapy będa musiały bardzo szybko się wyświetlać, na nich będą wykonywane inne operacje i przepisywanie z tablicy do TBitmap i zpowrotem zajmie zbyt dużo czasu.

A ta metoda ze wskaźnikami to właściwie niewiel wnosi. Niezaleznie od tego czy uzywam wskaznikow czy żywych bitmap działa tak samo:

var z : array [0..1000] of TBitmap;
i: integer;
begin
for i:=0 to 1000 do
begin
z[i] := TBitmap.create();
z[i].LoadFromFile('c:\z.bmp');
end;

Problem jest z uchwytami. W systemie jest ograniczona ilość uchwytów (Handle) dla Bitmap i nie można utworzyć ich zbyt wiele. W WinXP to działa lepiej. W Win98 i Me kończą się znacznie szybciej. Tyle wyczytałem i podejrzewam że stąd jest ten błąd - dlatego pytam czy to będzie działało na Win98?

Być może masz otwarte mniej programów i dlatego u ciebie działa dla 5000 a u mnie nie. Plik wczytuje za każdym razem ten sam i jest niewielki (po wczytaniu zajęte jest tylko około 650 Mb RAM)

Tomek

0

A konwersja na JPG przy wczytywaniu i pozostawienie w pamięci w formacie JPEG? :>

0
var Dane:TStringList;

function AddFile(const Name:String);
var S:TStringStream;
var B:TBitmap;
begin
  B:=TBitmap.Create;
  try
    B.LoadFromFile(Name);
    S:=TStringStream.Create('');
    try
      B.SaveToStream(S);
      Dane.Add(S.DataString);
    finally
      S.Free;
    end;
  finally
    B.Free;
  end;
end;

procedure GetBitmap(B:TBitmap;I:Integer);
var S:TStringStream;
begin
  S:=TStringStream.Create(Dane[I]);
  try
    B.LoadFromStream(S);
  finally
    S.Free;
  end;
end;

initialization Dane:=TStringList.Create;

finalization Dane.Free;

end.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0