Dziwny problem. Może ktoś może dać wgląd.Jakoś uszkodzone uchwyty?
Scenariusz 1. Mam w pamięci TBitmap, do której zapisuje się, podczas gdy mają miejsce złożone obliczenia, aby obliczyć kolor każdego piksela. Co jakiś czas (zwykle po każdej linii poziomej wypełnionej bitmapą) mapa TBitmap jest rysowana do obrazu w formularzu (image1.Canvas.Draw (0, 0, TBitmap). Większość czasu to działa dobrze, ale zauważyłem jeśli dla każdej linii bitmapowej istnieje wiele powolnych złożonych obliczeń (np. do obliczenia więcej niż 30 sekund lub minuty) to główna forma ma chwilowe "migotanie", które w jakiś sposób wymazuje bitmapę, więc wywołujemy tylko wywołania image.draw najnowszy obliczony linia a pierwsze y linie są wygaszone w mapie bitowej. mam wokół tego blokując bitmapę przed obliczeniami.
Scenariusz 2. to jest główny kłopot. piszę do TMemoryStream zamiast bitmapy .Te same transakcje są przeprowadzane w celu obliczenia każdej wartości piksela, a następnie każda wartość piksela jest zapisywana w TMemoryStream z memstream.Write (bytevalue, 1) podczas procesu. Na koniec wszystkich obliczeń zapisuję strumień do bitmapy z memstream.SaveToFile ("whatever.bmp"), a następnie uwalniam strumień z memstream.Free. Jeśli obliczenia są szybkie, strumień zapisuje się bez względu na rozmiar (wykonuję testy z wymiarami 10000x10000).
mogę nawet powiedzieć wynikowy plik będzie uszkodzony jako główne okno aplikacji/formularz ma nieznaczne migotanie jak to jest odmalowane. Kiedy tak się dzieje, to tak, jakby każdy uchwyt do map bitowych i TMemoryStream został zabity/odświeżony, więc istniejące dane są uszkodzone.
Wszelkie pomysły? To naprawdę jest do bani. Zwłaszcza, gdy każdy pojedynczy obraz może zająć godzinę, aby go utworzyć, aby odkryć, że gdy skończy się coś w tle, nastąpiło uszkodzenie mapy bitowej lub TMemoryStream.
Czy mogę zablokować uchwyt TMemoryStream tak, jak potrafię z bitmapą? To może pomóc. Lub jakąś deklarację, aby powiedzieć Delphi "Nie zadzieraj z moimi obiektami, nawet jeśli wygląda na to, że aplikacja trwa zbyt długo"
Czy ktoś zna powód końca w Delphi, który powoduje, że tak się dzieje.
Plik TMemoryStream jest tworzony wewnątrz procedury, która wykonuje wszystkie obliczenia, więc jest obiektem lokalnym. W przypadku wydania bitmapy mapa bitowa była zmienną globalną poza procedurą i tak się stało, więc nie sądzę, że jest to przyczyną.
Jest to również w systemie Windows 7, ale zauważyłem oryginalny problem bitmapy pod Vista.
Aktualizacja 1:
Przepraszamy za nie za pomocą komentarzy, ale nie jest restirction od rozmiaru tekstu ...
W odpowiedzi na Remy (i ktoś czytając to) ...
Pojedynczy gwintowany. W przypadku memorystream działa dobrze dla rozdzielczości 5000x5000, jeśli obliczenia są szybkie, ale nie powiedzie się, jeśli utwory są wolne.
jako podstawowy kod jest wzdłuż linii
SetupMemorystream;
for y:=0 to height do
for x:=0 to width do
DoCalcs;
SetByteValue;
end;
end;
SaveStream;
Jeśli DoCalcs jest stosunkowo szybki wtedy wszystko idzie zgodnie z planem. Jeśli jest wolny, otrzymuję uszkodzenie pliku TMemoryStream, a wynikowa mapa bitowa, w której zapisywany jest strumień, jest uszkodzona.
To było identyczne z używaniem w pamięci TBitmap, dopóki nie odkryłem, że mogę zablokować bitmapę, która zatrzymuje Delphi i/lub Windows ponownie przydziela nowy uchwyt do "kiedy chce", co psuje dane w bitmapie.
To zbyt wielki zbieg okoliczności, aby nie myśleć, że ten sam problem nie ma miejsca w przypadku TMemoryStream i jego obsługi.
Aktualizacja 2:
Jednym z bardziej pomocne może trochę info.
Gdy plik TMemoryStream zapisuje OK, wynikowy plik (dla mapy bitowej 5000x5000) ma rozmiar 75 000,054 bajtów.
Gdy zapisany strumień jest uszkodzony, wydaje się być wartością losową (o wielkości od momentu, w którym uchwyt został uszkodzony, dopóki strumień nie zostanie zapisany). Przykładowe rozmiary to 22 MB i 9 MB.
Kiedy patrzę na wynikowe pliki, to edytor heksadecymalny pokazuje, że początki plików są poprawne z częściami nagłówka, ale końce ogonów zostają w jakiś sposób obcięte.
To jest takie dziwne. W każdym razie mogę absolutnie na pewno przepłukać TMemoryStream po wywołaniu SaveToFile i przed uwolnieniem go?
Czy twój kod jest wielowątkowy? Jeśli nie, to nie ma mowy, że prędkość obliczeń może być causi na problemy, które opisałeś. Prawdopodobnie masz po prostu błędny kod, który zapisuje uszkodzone dane do bitmapy/strumienia. –
Zawsze możesz komentować swoje pytania i odpowiedzi oraz wszelkie odpowiedzi na zadawane pytania, nawet po 1 powtórzeniu. Powinieneś również móc edytować swoje pytanie. –
Strumień pamięci to tylko porcja pamięci zapakowana w klasę. VCL i RTL w żaden sposób nie będą z tym bałagani. Więc twój problem musi być gdzieś w kodzie. – Runner