AWARE [SYSTEMS] Imaging expertise voor de Delphi ontwikkelaar
AWare Systems, Imaging expertise voor de Delphi ontwikkelaar, Home TechTalks / VCL TGraphic grondbeginselen
AWare Systems on-line

Home
Custom development
Imaging
TechTalks
    Bestandformaat uit gegevens
    Tiling versus banding
    VCL TGraphic grondbeginselen
    Ongebruikte kleur
Company
Links

Talen

  English version
  Nederlandse versie

Contact

Informatie: info@awaresystems.be
Helpdesk: support@awaresystems.be
Verkoop: sales@awaresystems.be



Valid HTML 4.01!



Wat zit er in een Delphi VCL TGraphic, TPicture, TImage en hoe kan je converteren tussen verschillende grafische bestandsformaten?

> Wat zit er eigenlijk in een Delphi VCL TGraphic, TPicture, TImage? Wanneer gebruik
> ik welke grafische klassen? En hoe kan ik deze klassen gebruiken om conversies uit te
> voeren tussen verschillende grafische bestandformaten?

Er schijnt hieromtrent nogal wat verwarring te bestaan. De eigenlijke bedoeling van het TGraphic ontwerp wordt niet altijd goed begrepen, is op het design-vlak gecorrupteerd door de 'foute' en ontoereikende TBitmap, is verder slecht gedocumenteerd en wordt vaak verward met de functionaliteit van een TImage. Toch gaat het om een uiterst verfijnd ontwerp.

De korte (maar niet helemaal correcte) uitleg luidt als volgt:

  • Een TGraphic is bedoeld om een raster (afbeelding) te beheren en weet hoe het dat raster op een tekenoppervlak moet drawen (op een TCanvas, in Delphi-speak, of een DC op het Windows-niveau)
    • Een afgeleide van TGraphic, zoals TJpegImage of TBitmap bijvoorbeeld, kan zodanig ontworpen zijn dat het bovendien in staat is om een gegevens uit een welbepaald bestandsformaat in te lezen en/of deze in datzelfde formaat weg te schrijven . Een TJpegImage beheert dus een raster en weet hoe het kan worden gedrawd op een oppervlak, maar weet bovendien ook hoe dat raster vanuit een jpeg bestand moet worden gelezen, of hoe het naar een jpeg bestand moet worden weggeschreven in overeenstemming met de specificaties van het JPEG bestandsformaat.
    • Een Delphi TBitmap is multifunctioneel in die zin dat het de bovenstaande functionaliteit omvat, en het ook *het* grafische object bij uitstek op Windows-niveau is. Zo opgevat is een TBitmap dus ook een object dat min of meer onafhankelijk is van specifieke bestandsformaten en kan het bijvoorbeeld worden gebruikt om tijdelijke buffers en dergelijke te beheren.
    • Een TPicture lijkt op een TGraphic, maar is voor het overige erg verschillend van een TJpegImage of een TBitmap. Het is niet in staat om rechtstreeks een raster te beheren, maar beheert in plaats daarvan een TGraphic van om het even welk type. Zo is het in staat om bijv. een 'type selectie' functionaliteit toe te voegen aan de LoadFromFile methode, aangezien het uit de bestandsextensie in de bestandsnaam het juiste TGraphic-type kan afleiden, de juiste TGraphic-afgeleide kan construeren, en de eigenlijke Load-bewerking vervolgens kan delegeren aan dat beheerde TGraphic object.
  • Een Delphi TImage bevat en beheert een TPicture. Het is niet bedoeld om de functie van een Tpicture over te nemen of te vervangen, maar om deze uit te breiden met rendering in een User Interface context. Een onzichtbare TImage beheren louter om een beeld te beheren, bijvoorbeeld, is dus nonsens.

(De bovenstaande uitleg is niet helemaal correct in zoverre dat een TGraphic eigenlijk zelfs niet weet hoe het een raster moet beheren en drawen. Zelfs die functionaliteit wordt vervuld door de afgeleide objecten. Dat is een deugdelijk ontwerp omdat het bijvoorbeeld multi-page of video TGraphic-klassen mogelijk maakt, alsook zogenaamde 'tile array rasters' die een oplossing kunnen bieden voor het verwerken van grote afbeeldingen... Maar deze juistere uitleg staat misschien een goed begrip in de weg en bovendien zijn er niet zoveel multi-page of video-TGraphics te vinden, vandaar.)

Een courante toepassing van dit object ontwerp is de conversie van grafische bestandsformaten. Veronderstel dat u een JPEG bestand moet converteren in een BMP bestand. Dit houdt in dat u het JPEG-bestand in een raster moet inlezen om het vervolgens naar een BMP-bestand weg te schrijven. Voor het eerste deel van deze taak gebruiken we het TJpegImage-object aangezien dat object in staat is om een JPEG bestand te lezen en te decoderen. Het raster, dat door deze TJpegImage wordt beheerd, moet vervolgens worden overgezet naar een TBitmap-object. Dat TBitmap object kan dan op zijn beurt het BMP-bestand coderen en wegschrijven.

Als we omwille van leesbaarheid alle exception handling en dergelijke weglaten, komt dit in code neer op:

procedure ConvertJpegFileToBitmapFile(const SourceFilename, DestinationFilename: String);

var

jpeg: TJpegImage;

bmp: TBitmap;

begin

jpeg := TJpegImage.Create;

jpeg.LoadFromFile(SourceFilename);

bmp := TBitmap.Create;

bmp.Assign(jpeg);

bmp.SaveToFile(DestinationFilename);

bmp.Free;

jpeg.Free;

end;

De bovenstaande code maakt ook duidelijk wat de functie van de Assign-opdracht is. Intern worden deze TJpegImage en TBitmap objecten verondersteld rasters te beheren met behulp van gebruikstellers of "usage counters". Officieel kopieert de Assign-opdracht de inhoud van het raster van het jpeg-object naar het bmp-object. Dit houdt echter *niet* in dat er een tweede raster wordt gecreŽerd en de pixelgegevens worden gekopieerd. Wel komt het erop neer dat het rasterobject wordt gedeeld en dat diens gebruiksteller wordt verhoogd, zodat het geheugen niet hoeft te worden verdubbeld.

Geef ons een seintje als u op de hoogte wilt blijven van de veranderingen of toevoegingen aan deze pagina.