[delphi]Images inladen vertraagt listview

Pagina: 1
Acties:
  • 102 views sinds 30-01-2008
  • Reageer

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik heb een listview (een VirtualStringTree eigenlijk, maar dat maakt in dit geval niet zoveel uit) en in die listview pomp ik een rij bestandsnamen. Als de gebruiker een afbeelding kiest, dan wordt ie ernaast getoond in een image control. Dat is allemaal geen enkel probleem.

Het is alleen jammer dat als je met het toetsenbord door de lijst heen gaat bladeren, het laden van een image het bladeren vertraagt. Als je de de knop ingedrukt houdt, dan zie je zelfs 1 voor 1 alle plaatjes voorbij komen, maar pas als je de knop loslaat, zie je de selectie veranderen...

Okok, dit kan in een thread, maar daarmee los ik alleen niet de vertraging op, omdat je het laden/weergeven van een plaatje (iig een TJPEGImage) niet kan onderbreken. En dat terwijl er verschillende image viewers zijn die dit uiterst snel en soepel doen, dus daarmee wil ik maar zeggen dat het wel degelijk mogelijk is

Wie heeft suggesties?

offtopic:
en nu eerst slapen :)

日本!🎌


Verwijderd

ff snel:

Oplossing 1: Cachen van de images

Oplossing 2: Met een timer kijken of de gebruiker wel een minimaal een halve second (of meer) op een image naam staat en dan pas laden

Oplossing 3: Code van TJpegImage hacken zodat laden wel kan worden afgebroken

[ Voor 22% gewijzigd door Verwijderd op 23-12-2004 01:38 ]


Verwijderd

Ik wel, vrij eenvoudig eigenlijk. Ik neem aan dat je een event gebruikt om dat plaatje te laden.

Zet er een timertje tussen, zoiets dus:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TForm1.ListView1Change(Sender: TObject; Item: TListItem; Change: TItemChange);
begin
  Form1.FileName:=ListView1.Items.Item[Listview1.ItemIndex].Caption;
  If Timer1.Enabled then Timer1.Enabled:=False;
  Timer1.Enabled;
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:=False;
  Form1.Image1.Picture.LoadFromFile(Form1.FileName);
end;

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Hmm, zo'n timer is misschien wel een optie, maar betekent dat niet dat als een plaatje aan het laden is, de applicatie nog steeds blokkeert? Misschien dat ik dat concept dan maar moet uitbouwen tot een thread... maarja, dat heeft ook weer z'n nadelen als je met GUI dingen gaat spelen.

Cachen is overigens geen optie, als er 200 jpegs van 1MB in staan, kost dat minimaal 200MB :)

日本!🎌


  • paulh
  • Registratie: Juli 1999
  • Laatst online: 11-05 14:30
_Thanatos_ schreef op donderdag 23 december 2004 @ 09:35:
Hmm, zo'n timer is misschien wel een optie, maar betekent dat niet dat als een plaatje aan het laden is, de applicatie nog steeds blokkeert? Misschien dat ik dat concept dan maar moet uitbouwen tot een thread... maarja, dat heeft ook weer z'n nadelen als je met GUI dingen gaat spelen.

Cachen is overigens geen optie, als er 200 jpegs van 1MB in staan, kost dat minimaal 200MB :)
Een cache hoeft niet per definitie alle plaatjes te cachen. Doe er anders 20 of zo. Kan allicht schelen als er vaak bijvoorbeeld op de eerste plaatjes geklikt wordt.

[ZwareMetalen.com] - [Kom in aktie tegen de CO2 maffia]


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 13:23

mulder

ik spuug op het trottoir

Kun je het plaatje niet pas tonen in het keyup-event?

oogjes open, snaveltjes dicht


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
paulh schreef op donderdag 23 december 2004 @ 09:44:
[...]
Een cache hoeft niet per definitie alle plaatjes te cachen. Doe er anders 20 of zo. Kan allicht schelen als er vaak bijvoorbeeld op de eerste plaatjes geklikt wordt.
Mwa, het is alles of niks, denk ik. Het is geen image viewer applicatietje, maar iig een lijstje waar de gebruiker helemaal van boven naar beneden doorheen zal lopen. Hooguit nog een keer terug om te checken.

Ik zou wel een combinatie van een thread en cache kunnen doen. Een ding dat zegmaar de plaatjes "in het voren" decodeert, in een low-priority thread. Maar dan misschien de 10 volgende en de tien vorige ofzo...
Don Facundo schreef op donderdag 23 december 2004 @ 10:04:
Kun je het plaatje niet pas tonen in het keyup-event?
Dat vind ik niet zo netjes. Bovendien werk ik met een VirtualStringTree, en die heeft gewoon een event OnFocusChanged die je hiervoor dient te gebruiken.

[ Voor 20% gewijzigd door _Thanatos_ op 23-12-2004 16:43 ]

日本!🎌


Verwijderd

_Thanatos_ schreef op donderdag 23 december 2004 @ 09:35:
Hmm, zo'n timer is misschien wel een optie, maar betekent dat niet dat als een plaatje aan het laden is, de applicatie nog steeds blokkeert?
Dat wel inderdaad. Met het standaard delphi TImage component, doe je daar niets tegen. Dan zou je op zoek moeten gaan naar een component waarbij het laden af te breken is en welke in een thread laden, die zijn er wel.
Misschien dat ik dat concept dan maar moet uitbouwen tot een thread... maarja, dat heeft ook weer z'n nadelen als je met GUI dingen gaat spelen.
Als je een thread maakt, heb je geen timer meer nodig uiteraard. En nadelen als je met GUI gaat spelen? Hoezo? Zolang je maar synchroniseert gaat alles goed hoor :P

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 12:05

Tomatoman

Fulltime prutser

Verwijderd schreef op donderdag 23 december 2004 @ 01:37:
Oplossing 3: Code van TJpegImage hacken zodat laden wel kan worden afgebroken
Dat gaat niet lukken. De implementatie in de JPEG unit maakt gebruik van een standaard in Windows aanwezige library met functies om een JPEG image te tonen. De code zit zo in elkaar dat je het laden niet tussentijds kunt onderbreken. De enige oplossing om hier onderuit te komen is een andere implementatie van de JPEG unit te schrijven of de code volledig aan te passen. Een simpele hack om het laden te onderbreken is helaas niet mogelijk (tenzij je de thread die de JPEG laadt hardhandig de nek omdraait.

Zie ook _Thanatos_' eerdere topic: [rml][ delphi] stop met laden van jpeg[/rml]. Daar had ik al aangegeven dat je alleen progress events hebt na het lezen van iedere scanline in het bestand. Aangezien verreweg de meeste JPEG images maar uit één scanline bestaan, vinden er tijdens het inlezen geen events plaats waarop je kunt reageren door het scannen te onderbreken.

Een goede grap mag vrienden kosten.


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Nou, ik heb inmiddels een mooie thread gemaakt en alle gebruikelijke AV's om zeep geholpen, want Delphi spul is nou eenmaal niet altijd en overal thread-safe.

Maar nu treedt er een nieuw probleem op. Een plaatje dat in de thread wordt ingeladen en in een cache wordt opgeslagen (een TTntStringList, waarin een filename+TGraphic komt) is soms helemaal wit. Terwijl als ik de cache niet gebruik, alle plaatjes *altijd* correct inladen. Het is ook niet altijd hetzelfde plaatje, en het zijn er ook altijd maar 1 of 2 van de 10. Er treedt geen exception op, het lijkt alsof ie iets gewoon niet snapt. Ook heb ik LoadFromStream al gesynchronized, maar dat maakt ook niets uit. Het gekke is ook dat als ik door de code heen stap, het *altijd* goed gaat :?

日本!🎌


Verwijderd

_Thanatos_ schreef op zaterdag 25 december 2004 @ 20:58:
Ook heb ik LoadFromStream al gesynchronized, maar dat maakt ook niets uit. Het gekke is ook dat als ik door de code heen stap, het *altijd* goed gaat :?
Probeer eens bij project -> options op het tabblad 'compiler' de optie 'Optimization' uit te zetten.

Meer waarschijnlijker lijkt me dat hij gewoon nog niet klaar is met laden als je 'm al laat zien. Dat zou verklaren waarom hij met steppen het wel doet, aangezien je zelf trager stepped dan je computer, zeg maar.

Wil je er meer over weten, zul je toch echt met code op de proppen moeten komen :P

Nog een mogelijkheid.. doe even een timage.invalidate nadat je de pic geassigned hebt, of geef 'm direct een repaint.

[ Voor 14% gewijzigd door Verwijderd op 25-12-2004 21:48 ]


  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 15-05 14:44

_Thanatos_

Ja, en kaal

Topicstarter
Ik heb al iets handiger gevonden. Ik las in een nieuwsgroep dat TJPEGImage niet thread-safe is, dus daar ben ik dan lekker mee. Maar het blijkt dat als ik em aan een TBitmap assign (dus em niet erop tekenen, want dat gaat ook fout), en die vervolgens cache, dan gaat het prima (tot nu toe).

Toch vreemd dat ze niet ff de moeite nemen om het thread-safe te maken.

Dat het tijdens het door de code stappen wel goed ging, is waarschijnlijk te danken aan het feit dat het dan langzamer gaat, en thread-safety minder een issue is.

日本!🎌

Pagina: 1