Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Maak UWP-apps (Universal Windows Platform) met vloeiende animaties, hoge framesnelheid en high-performance media capture en afspelen.
Animaties vloeiend maken
Een belangrijk aspect van UWP-apps is soepele interacties. Dit omvat aanraakmanipulaties die 'aan uw vinger blijven', vloeiende overgangen en animaties, en kleine bewegingen die feedback geven over invoer. In het XAML-framework is er een thread genaamd de samenstellingsthread die is toegewezen aan de samenstelling en animatie van visuele elementen van een app. Omdat de samenstellingsthread gescheiden is van ui-thread (de thread die framework- en ontwikkelaarscode uitvoert), kunnen apps een consistente framesnelheid en vloeiende animaties bereiken, ongeacht ingewikkelde indelingspassen of uitgebreide berekeningen. In deze sectie ziet u hoe u de samenstellingsthread gebruikt om de animaties van een app vloeiend te houden. Zie Overzicht van animatiesvoor meer informatie over animaties. Zie De ui-thread responsief houdenvoor meer informatie over het vergroten van de reactiesnelheid van een app tijdens het uitvoeren van intensieve berekeningen.
Onafhankelijk gebruiken in plaats van afhankelijke animaties
Onafhankelijke animaties kunnen worden berekend van begin tot eind op het moment van maken, omdat wijzigingen in de eigenschap die wordt geanimeerd, geen invloed hebben op de rest van de objecten in een scène. Onafhankelijke animaties kunnen daarom worden uitgevoerd op de samenstellingsthread in plaats van de UI-thread. Dit garandeert dat ze soepel blijven omdat de samenstellingsthread met een consistente frequentie wordt bijgewerkt.
Al deze typen animaties zijn gegarandeerd onafhankelijk:
Objectanimaties met sleutelframes
Animaties met nulduur
Animaties voor de eigenschappen Canvas.Left en Canvas.Top
Animaties naar de eigenschap UIElement.Opacity
Animaties van eigenschappen van het type Brush bij het richten op de SolidColorBrush.Color subeigenschap
Animaties voor de volgende UIElement eigenschappen bij het richten op subeigenschappen van deze terugkeertypen:
Afhankelijke animaties zijn van invloed op de indeling, die daarom niet kan worden berekend zonder extra invoer van de UI-thread. Afhankelijke animaties bevatten wijzigingen in eigenschappen zoals Breedte en Hoogte. Afhankelijke animaties worden standaard niet uitgevoerd en vereisen een opt-in van de app-ontwikkelaar. Wanneer deze optie is ingeschakeld, worden ze probleemloos uitgevoerd als de UI-thread wordt gedeblokkeerd, maar ze beginnen te stutteren als het framework of de app veel ander werk aan de UI-thread doet.
Bijna alle animaties in het XAML-framework zijn standaard onafhankelijk, maar er zijn enkele acties die u kunt ondernemen om deze optimalisatie uit te schakelen. Pas op voor deze scenario's, met name:
- Het instellen van de eigenschap EnableDependentAnimation zodat een afhankelijke animatie kan worden uitgevoerd op de UI-thread. Converteer deze animaties naar een onafhankelijke versie. U kunt bijvoorbeeld animatie toepassen op ScaleTransform.ScaleX- en ScaleTransform.ScaleY- in plaats van de Width en Height van een object. Wees niet bang om objecten zoals afbeeldingen en tekst te schalen. Het framework past alleen bilineaire schaalaanpassing toe terwijl de ScaleTransform- wordt geanimeerd. De afbeelding/tekst wordt op de uiteindelijke grootte gerasteriseerd om altijd duidelijk te blijven.
- Het maken van updates per frame, die effectief afhankelijke animaties zijn. Een voorbeeld hiervan is het toepassen van transformaties in de handler van de CompositonTarget.Rendering gebeurtenis.
- Het uitvoeren van animaties die als onafhankelijk worden beschouwd in een element met de eigenschap CacheMode ingesteld op BitmapCache-. Dit wordt beschouwd als afhankelijk omdat de cache opnieuw moet worden gerasterd voor elk frame.
Animeer een WebView of MediaPlayerElement niet
Webinhoud binnen een WebView-besturingselement wordt niet rechtstreeks weergegeven door het XAML-framework en vereist extra werk om samen te voegen met de rest van de scène. Dit extra werk telt op bij het aanbrengen van animaties voor het besturingselement op het scherm en kan mogelijk synchronisatieproblemen veroorzaken (de HTML-inhoud wordt bijvoorbeeld mogelijk niet gesynchroniseerd met de rest van de XAML-inhoud op de pagina). Wanneer u een WebView- besturingselement wilt animeren, wisselt u het om voor een WebViewBrush gedurende de animatie.
Het animeren van een MediaPlayerElement- is ook een slecht idee. Afgezien van de prestatieschade kan dit leiden tot scheuring of andere artefacten in de video-inhoud die wordt afgespeeld.
Opmerking De aanbevelingen in dit artikel voor MediaPlayerElement zijn ook van toepassing op MediaElement. MediaPlayerElement is alleen beschikbaar in Windows 10, versie 1607, dus als u een app voor een eerdere versie van Windows maakt, moet u MediaElementgebruiken.
Oneindige animaties spaarzaam gebruiken
De meeste animaties worden gedurende een opgegeven tijdsduur uitgevoerd, maar als u de eigenschap Timeline.Duration op Forever instelt, kan een animatie voor onbepaalde tijd worden uitgevoerd. We raden u aan het gebruik van oneindige animaties te minimaliseren omdat ze voortdurend CPU-resources verbruiken en kunnen voorkomen dat de CPU een lage of niet-actieve status krijgt, waardoor deze sneller uit de stroom komt.
Het toevoegen van een handler voor CompositionTarget.Rendering is vergelijkbaar met het uitvoeren van een oneindige animatie. Normaal gesproken is de UI-thread alleen actief wanneer er werk moet worden uitgevoerd, maar het toevoegen van handler voor deze gebeurtenis dwingt het om elk frame uit te voeren. Verwijder de handler wanneer er geen werk te doen is en registreer deze opnieuw wanneer het weer nodig is.
De animatiebibliotheek gebruiken
De Windows.UI.Xaml.Media.Animation naamruimte bevat een bibliotheek met krachtige, vloeiende animaties die een uiterlijk hebben en consistent zijn met andere Windows-animaties. De relevante klassen hebben 'Thema' in hun naam en worden beschreven in Overzicht animaties. Deze bibliotheek ondersteunt veel veelvoorkomende animatiescenario's, zoals het maken van animaties voor de eerste weergave van de app en het maken van status- en inhoudsovergangen. We raden u aan deze animatiebibliotheek waar mogelijk te gebruiken om de prestaties en consistentie voor uwP-gebruikersinterface te verbeteren.
Opmerking De animatiebibliotheek kan niet alle mogelijke eigenschappen animeren. Zie voor XAML-scenario's waarin de animatiebibliotheek niet van toepassing is Storyboarded animaties.
Animeren CompositeTransform3D-eigenschappen onafhankelijk
U kunt elke eigenschap van een CompositeTransform3D onafhankelijk animeren, dus pas alleen de animaties toe die u nodig hebt. Zie UIElement.Transform3D-voor voorbeelden en meer informatie. Zie voor meer informatie over animatie-animaties animaties met verhaalbord en animaties voor keyframe- en easing-functies.
Mediabronnen optimaliseren
Audio, video en afbeeldingen zijn aantrekkelijke vormen van inhoud die de meeste apps gebruiken. Naarmate media-opnamesnelheden toenemen en inhoud wordt verplaatst van standaarddefinitie naar high definition, neemt de hoeveelheid resources toe die nodig zijn om deze inhoud op te slaan, te decoderen en af te spelen. Het XAML-framework bouwt voort op de nieuwste functies die zijn toegevoegd aan de UWP-media-engines, zodat apps deze verbeteringen gratis krijgen. Hier leggen we enkele extra trucs uit waarmee u optimaal gebruik kunt maken van media in uw UWP-app.
Mediastreams vrijgeven
Mediabestanden zijn een aantal van de meest voorkomende en dure resources die apps doorgaans gebruiken. Omdat mediabestandsbronnen de grootte van de geheugenvoetafdruk van uw app aanzienlijk kunnen vergroten, moet u de koppeling naar media vrijgeven zodra de app klaar is met het gebruik ervan.
Als uw app bijvoorbeeld werkt met een RandomAccessStream- of een IInputStream--object, moet u de sluitmethode voor het object aanroepen wanneer uw app klaar is met het gebruik ervan, om het onderliggende object vrij te geven.
Video afspelen in volledig scherm weergeven, indien mogelijk
Gebruik in UWP-apps altijd de eigenschap IsFullWindow op de MediaPlayerElement- om volledige vensterweergave in en uit te schakelen. Dit zorgt ervoor dat optimalisaties op systeemniveau worden gebruikt tijdens het afspelen van media.
Het XAML-framework kan de weergave van video-inhoud optimaliseren wanneer dit het enige is dat wordt weergegeven, wat resulteert in een ervaring die minder vermogen verbruikt en hogere framesnelheden oplevert. Voor het efficiënt afspelen van media stelt u de grootte van een MediaPlayerElement- in op de breedte en hoogte van het scherm en geeft u geen andere XAML-elementen weer
Er zijn legitieme redenen om XAML-elementen over te leggen op een MediaPlayerElement die de volledige breedte en hoogte van het scherm in beslag neemt, bijvoorbeeld ondertiteling of tijdelijke transportcontroles. Zorg ervoor dat u deze elementen (Visibility="Collapsed") verbergt wanneer ze niet nodig zijn om het afspelen van media terug te zetten in de meest efficiënte staat.
Deactiveren en besparen van vermogen weergeven
Als u wilt voorkomen dat de weergave wordt gedeactiveerd wanneer gebruikersactie niet meer wordt gedetecteerd, zoals wanneer een app video afspeelt, kunt u DisplayRequest.RequestActiveaanroepen.
Als u energie en batterijduur wilt besparen, moet u DisplayRequest.RequestRelease aanroepen om de weergaveaanvraag vrij te geven zodra deze niet meer nodig is.
Hier volgen enkele situaties waarin u de weergaveaanvraag moet vrijgeven:
- Het afspelen van video's wordt onderbroken, bijvoorbeeld door gebruikersactie, buffering of aanpassing vanwege beperkte bandbreedte.
- De weergave stopt. De video is bijvoorbeeld klaar met afspelen of de presentatie is voorbij.
- Er is een afspeelfout opgetreden. Bijvoorbeeld netwerkverbindingsproblemen of een beschadigd bestand.
Andere elementen aan de zijkant van ingesloten video plaatsen
Apps bieden vaak een ingesloten weergave waarin video wordt afgespeeld op een pagina. U hebt nu duidelijk de optimalisatie van het volledige scherm verloren omdat de MediaPlayerElement niet de grootte van de pagina heeft en dat er andere XAML-objecten zijn weergegeven. Pas op dat u deze modus onbedoeld invoert door een rand rond een MediaPlayerElementte tekenen.
Teken geen XAML-elementen boven op video wanneer deze zich in de ingesloten modus bevindt. Als u dat doet, wordt het framework gedwongen om wat extra werk te doen om de scène samen te stellen. Het plaatsen van transportbesturingselementen onder een ingesloten media-element in plaats van op de video is een goed voorbeeld van optimaliseren voor deze situatie. In deze afbeelding geeft de rode balk een reeks transportbesturingselementen aan (afspelen, onderbreken, stoppen, enzovoort).
Plaats deze besturingselementen niet boven op media die niet op het volledige scherm staan. Plaats in plaats daarvan de transportcontroles ergens buiten het gebied waar de media worden weergegeven. In de volgende afbeelding worden de besturingselementen onder de media geplaatst.
Vertraging bij het instellen van de bron voor een MediaPlayerElement
Media-engines zijn dure objecten en het XAML-framework vertraagt het laden van DLL's en het maken van grote objecten zo lang mogelijk. De MediaPlayerElement wordt gedwongen dit werk uit te voeren nadat de bron is ingesteld via de eigenschap Source. Dit instellen wanneer de gebruiker echt klaar is om media af te spelen, vertraagt de meeste kosten die zijn gekoppeld aan het MediaPlayerElement zo lang mogelijk.
MediaPlayerElement.PosterSource instellen
Als u MediaPlayerElement.PosterSource instelt, kan XAML bepaalde GPU-resources vrijgeven die anders zouden zijn gebruikt. Met deze API kan een app zo weinig mogelijk geheugen gebruiken.
Mediascrubing verbeteren
Scrubbing is altijd een moeilijke taak voor mediaplatforms om echt responsief te maken. Over het algemeen doen mensen dit door de waarde van een schuifregelaar te wijzigen. Hier volgen enkele tips om dit zo efficiënt mogelijk te maken:
- Werk de waarde van Schuifregelaar bij op basis van de timer die de Positie op de MediaPlayerElement.MediaPlayeropvraagt. Zorg ervoor dat u een redelijke updatefrequentie gebruikt voor uw timer. De eigenschap Position wordt tijdens het afspelen slechts elke 250 milliseconden bijgewerkt.
- De grootte van de stapfrequentie op de schuifregelaar moet worden geschaald met de lengte van de video.
- Abonneer u op de PointerPressed, PointerMoved, PointerReleased gebeurtenissen op de schuifregelaar om de eigenschap PlaybackRate in te stellen op 0 wanneer de gebruiker de duim van de schuifregelaar sleept.
- Stel in de PointerReleased gebeurtenishandler de mediapositie handmatig in op de schuifregelaarpositie om optimale uitlijning van de schuifregelaar te bereiken tijdens het doorspoelen.
Videoresolutie afstemmen op apparaatresolutie
Het decoderen van video neemt veel geheugen- en GPU-cycli in beslag, dus kies een video-indeling dicht bij de resolutie waarop deze wordt weergegeven. Het is niet mogelijk om de resources te gebruiken om 1080 video's te decoderen als deze naar een veel kleinere grootte worden geschaald. Veel apps hebben niet dezelfde video gecodeerd bij verschillende resoluties; maar als deze beschikbaar is, gebruikt u een codering die zich dicht bij de resolutie bevindt waarop deze wordt weergegeven.
Aanbevolen indelingen kiezen
Selectie van media-indeling kan een gevoelig onderwerp zijn en wordt vaak aangestuurd door zakelijke beslissingen. Vanuit het perspectief van UWP-prestaties raden we H.264-video aan als primaire video-indeling en AAC en MP3 als de voorkeursaudioindelingen. Voor het afspelen van lokale bestanden is MP4 de voorkeursbestandscontainer voor video-inhoud. H.264-decodering wordt versneld via de meest recente grafische hardware. Hoewel hardwareversnelling voor VC-1-decodering algemeen beschikbaar is, is voor een grote set grafische hardware op de markt de versnelling in veel gevallen beperkt tot een gedeeltelijk versnellingsniveau (of IDCT-niveau), in plaats van een hardware-offload op vol vermogen (VLD-modus).
Als u volledige controle hebt over het proces voor het genereren van video-inhoud, moet u erachter komen hoe u een goede balans kunt houden tussen compressie-efficiëntie en GOP-structuur. Relatief kleinere GOP-grootte met B-afbeeldingen kan de prestaties in zoek- of trucmodi verhogen.
Wanneer je korte, lage-latentie audio-effecten, bijvoorbeeld in games, toevoegt, gebruik WAV-bestanden met niet-gecomprimeerde PCM-gegevens om de verwerkingsoverhead te verminderen die gebruikelijk is bij gecomprimeerde audioformaten.
Afbeeldingsbronnen optimaliseren
Afbeeldingen schalen naar de juiste grootte
Afbeeldingen worden vastgelegd met zeer hoge resoluties, wat ertoe kan leiden dat apps meer CPU gebruiken bij het decoderen van de afbeeldingsgegevens en meer geheugen nadat ze vanaf de schijf zijn geladen. Maar er is geen zin om een afbeelding met hoge resolutie in het geheugen te decoderen en op te slaan om deze kleiner dan de eigen grootte weer te geven. Maak in plaats daarvan een versie van de afbeelding op de exacte grootte die op het scherm wordt getekend, met behulp van de eigenschappen DecodePixelWidth en DecodePixelHeight.
Doe dit niet:
<Image Source="ms-appx:///Assets/highresCar.jpg"
Width="300" Height="200"/> <!-- BAD CODE DO NOT USE.-->
Ga in plaats daarvan als volgt te werk:
<Image>
<Image.Source>
<BitmapImage UriSource="ms-appx:///Assets/highresCar.jpg"
DecodePixelWidth="300" DecodePixelHeight="200"/>
</Image.Source>
</Image>
De eenheden voor Decode PixelWidth en Decode PixelHeight zijn standaard fysieke pixels. De eigenschap DecodePixelType kan worden gebruikt om dit gedrag te wijzigen: het instellen van DecodePixelType op Logical resulteert erin dat de decodeergrootte automatisch rekening houdt met de huidige schaalfactor van het systeem, vergelijkbaar met andere XAML-inhoud. Het zou daarom over het algemeen geschikt zijn om DecodePixelType in te stellen op Logisch als u bijvoorbeeld DecodePixelWidth en DecodePixelHeight wilt laten overeenkomen met de eigenschappen Hoogte en Breedte van de controle Afbeelding waarin de afbeelding wordt weergegeven. Met het standaardgedrag van het gebruik van fysieke pixels moet u zelf rekening houden met de huidige schaalfactor van het systeem; en u moet luisteren naar meldingen voor schaalwijzigingen voor het geval de gebruiker de weergavevoorkeuren wijzigt.
Als Decode PixelWidth/Height expliciet groter is dan de afbeelding wordt weergegeven op het scherm, gebruikt de app onnodig extra geheugen ( maximaal 4 bytes per pixel), wat snel duur wordt voor grote afbeeldingen. De afbeelding wordt ook omlaag geschaald met bilineaire schaalaanpassing, waardoor deze wazig kan lijken voor grote schaalfactoren.
Als DecodePixelWidth/DecodePixelHeight expliciet kleiner is ingesteld dan waarop de afbeelding op het scherm wordt weergegeven, dan wordt deze opgeblazen en kan hij pixelachtig lijken.
In sommige gevallen waarin een geschikte decodeergrootte niet van tevoren kan worden bepaald, moet u vertrouwen op XAML's automatische decodering naar de juiste grootte. Dit zal een zo goed mogelijke poging doen om de afbeelding op de juiste grootte te decoderen als een expliciete DecodePixelWidth/DecodePixelHeight niet is opgegeven.
U moet een expliciete decodeergrootte instellen als u de grootte van de afbeeldingsinhoud van tevoren kent. U moet ook in combinatie Decode PixelType instellen op Logische als de opgegeven decodegrootte relatief is ten opzichte van andere XAML-elementgrootten. Als u bijvoorbeeld expliciet de inhoudsgrootte instelt met Image.Width en Image.Height, kunt u Decode PixelType instellen op Decode PixelType.Logical om dezelfde logische pixeldimensies te gebruiken als een afbeeldingsbesturingselement en vervolgens expliciet BitmapImage.Decode PixelWidth en/of BitmapImage.Decode PixelHeight gebruiken om de grootte van de afbeelding te bepalen om potentieel grote geheugenbesparingen te bereiken.
Houd er rekening mee dat Image.Stretch moet worden overwogen bij het bepalen van de grootte van de gedecodeerde inhoud.
Decoderen met de juiste grootte
In het geval dat u geen expliciete decoderingsgrootte instelt, probeert XAML het geheugen optimaal te besparen door een afbeelding te decoderen naar de exacte grootte die op het scherm wordt weergegeven volgens de oorspronkelijke indeling van de pagina. U wordt aangeraden om uw toepassing zo te schrijven dat deze functie waar mogelijk wordt gebruikt. Deze functie wordt uitgeschakeld als aan een van de volgende voorwaarden wordt voldaan.
- De BitmapImage is verbonden met de live XAML-structuur nadat de inhoud is ingesteld met SetSourceAsync of UriSource.
- De afbeelding wordt gedecodeerd met synchrone decodering, zoals SetSource.
- De afbeelding is verborgen door Opacity op 0 in te stellen of Visibility op Collapsed te zetten op het hostafbeeldingselement of een bovenliggend element.
- Het besturingselement of penseel van de afbeelding maakt gebruik van een Stretch van None.
- De afbeelding wordt gebruikt als een NineGrid-.
-
CacheMode="BitmapCache"is ingesteld op het afbeeldingselement of op een ouder-element. - Het afbeeldingsborstel is niet rechthoekig (bijvoorbeeld wanneer deze wordt toegepast op een vorm of op tekst).
In de bovenstaande scenario's is het instellen van een expliciete decodergrootte de enige manier om geheugenbesparing te bereiken.
U moet altijd een BitmapImage- aan de levende boom koppelen alvorens de bron in te stellen. Telkens wanneer een afbeeldingselement of penseel wordt opgegeven in markeringen, is dit automatisch het geval. Hieronder ziet u voorbeelden onder de kop 'Voorbeelden van levende bomen'. Vermijd altijd het gebruik van SetSource en gebruik in plaats daarvan SetSourceAsync- bij het instellen van een stroombron. Het is een goed idee om te voorkomen dat de inhoud van de afbeelding wordt verborgen (door geen zichtbaarheid of samengevouwen weergave) terwijl u wacht tot de ImageOpened gebeurtenis wordt gegenereerd. Dit is een beoordelingskwestie: u profiteert niet van automatische decodering in de juiste grootte als het wordt gedaan. Als uw app in eerste instantie afbeeldingsinhoud moet verbergen, moet deze ook de grootte van de decoderen expliciet instellen, indien mogelijk.
voorbeelden van livestructuur
Voorbeeld 1 (goed): URI (Uniform Resource Identifier) die is opgegeven in markeringen.
<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>
Voorbeeld 2 opmaak - URI opgegeven in code-behind.
<Image x:Name="myImage"/>
Voorbeeld 2 code-behind (goed): Verbind de BitmapImage met de boomstructuur voordat u de UriSource instelt.
var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
Voorbeeld 2 code-behind (slecht): de UriSource van de BitmapImage instellen voordat deze wordt verbonden met de boomstructuur.
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;
Optimalisaties voor caching
Cachingoptimalisaties zijn van kracht voor afbeeldingen die gebruikmaken van UriSource- om inhoud van een app-pakket of van het web te laden. De URI wordt gebruikt om de onderliggende inhoud uniek te identificeren en intern zal het XAML-framework de inhoud niet meerdere keren downloaden of decoderen. In plaats daarvan worden de software- of hardwarebronnen in de cache gebruikt om de inhoud meerdere keren weer te geven.
De uitzondering op deze optimalisatie is als de afbeelding meerdere keren wordt weergegeven op verschillende resoluties (die expliciet of via automatische decodering van de juiste grootte kunnen worden opgegeven). Elke cachevermelding slaat ook de resolutie van de afbeeldingen op, en als XAML een afbeelding niet kan vinden met een bron-URI die overeenkomt met de vereiste resolutie, dan wordt een nieuwe versie in die grootte gedecodeerd. De gecodeerde afbeeldingsgegevens worden echter niet opnieuw gedownload.
Daarom moet u het gebruik van UriSource- bij het laden van afbeeldingen uit een app-pakket omarmen en voorkomen dat u een bestandsstroom gebruikt en SetSourceAsync- wanneer dit niet nodig is.
Afbeeldingen in gevirtualiseerde panelen (bijvoorbeeld ListView)
Als een afbeelding uit de boom wordt verwijderd—omdat de app deze expliciet heeft verwijderd, of omdat deze zich in een modern gevirtualiseerd deelvenster bevindt en impliciet is verwijderd wanneer deze uit zicht werd gescrold—optimaliseert XAML het geheugengebruik door de hardwarebronnen voor de afbeelding vrij te geven omdat ze niet meer nodig zijn. Het geheugen wordt niet onmiddellijk vrijgegeven, maar pas tijdens de frame-update die plaatsvindt één seconde nadat het afbeeldingselement niet meer in de boom staat.
Daarom moet u ernaar streven om moderne gevirtualiseerde panelen te gebruiken om lijsten met afbeeldingsinhoud te hosten.
Software-gerasterde afbeeldingen
Wanneer een afbeelding wordt gebruikt voor een niet-rechthoekige kwast of voor een NineGrid-, gebruikt de afbeelding een pad voor softwarerasterisatie, waardoor afbeeldingen helemaal niet worden geschaald. Daarnaast moet er een kopie van de afbeelding worden opgeslagen in zowel het softwaregeheugen als het hardwaregeheugen. Als een afbeelding bijvoorbeeld wordt gebruikt als een kwast voor een ellips, wordt de potentieel grote volledige afbeelding tweemaal intern opgeslagen. Wanneer u NineGrid of een niet-rechthoekige kwast gebruikt, moet uw app de afbeeldingen vooraf schalen naar ongeveer de grootte waarop ze worden weergegeven.
Achtergrondthread voor het laden van afbeeldingen
XAML heeft een interne optimalisatie waarmee de inhoud van een afbeelding asynchroon kan worden gedecodeerd naar een oppervlak in hardwaregeheugen zonder dat hiervoor een tussenliggend oppervlak in softwaregeheugen nodig is. Dit vermindert het piekgeheugengebruik en de renderinglatentie. Deze functie wordt uitgeschakeld als aan een van de volgende voorwaarden wordt voldaan.
- De afbeelding wordt gebruikt als een NineGrid-.
-
CacheMode="BitmapCache"is ingesteld op het afbeeldingselement of op een ouder-element. - Het afbeeldingsborstel is niet rechthoekig (bijvoorbeeld wanneer deze wordt toegepast op een vorm of op tekst).
SoftwareBitmapSource
De SoftwareBitmapSource klasse wisselt interoperabele niet-gecomprimeerde afbeeldingen uit tussen verschillende WinRT-naamruimten, zoals BitmapDecoder-, camera-API's en XAML. Deze klasse obviaeert een extra kopie die doorgaans nodig zou zijn met WriteableBitmapen dat helpt piekgeheugen en latentie van bron-naar-scherm te verminderen.
De SoftwareBitmap- die brongegevens levert, kan ook worden geconfigureerd voor het gebruik van een aangepaste IWICBitmap om een herlaadbare backing store te bieden waarmee de app geheugen opnieuw kan toewijzen zoals het nodig acht. Dit is een geavanceerde C++-use case.
Uw app moet gebruikmaken van SoftwareBitmap en SoftwareBitmapSource om samen te werken met andere WinRT-API's die afbeeldingen produceren en gebruiken. En uw app moet SoftwareBitmapSource gebruiken bij het laden van niet-gecomprimeerde afbeeldingsgegevens in plaats van WriteableBitmapte gebruiken.
GetThumbnailAsync gebruiken voor miniaturen
Een use case voor het schalen van afbeeldingen is het maken van miniaturen. Hoewel u Decode PixelWidth en Decode PixelHeight- kunt gebruiken om kleine versies van afbeeldingen te bieden, biedt UWP nog efficiëntere API's voor het ophalen van miniaturen. GetThumbnailAsync biedt de thumbnails voor afbeeldingen die door het bestandssysteem al zijn gecachet. Dit biedt nog betere prestaties dan de XAML-API's, omdat de afbeelding niet hoeft te worden geopend of gedecodeerd.
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".bmp");
picker.FileTypeFilter.Add(".jpg");
picker.FileTypeFilter.Add(".jpeg");
picker.FileTypeFilter.Add(".png");
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
StorageFile file = await picker.PickSingleFileAsync();
StorageItemThumbnail fileThumbnail = await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 64);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(fileThumbnail);
Image img = new Image();
img.Source = bmp;
Dim picker As New FileOpenPicker()
picker.FileTypeFilter.Add(".bmp")
picker.FileTypeFilter.Add(".jpg")
picker.FileTypeFilter.Add(".jpeg")
picker.FileTypeFilter.Add(".png")
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
Dim file As StorageFile = Await picker.PickSingleFileAsync()
Dim fileThumbnail As StorageItemThumbnail = Await file.GetThumbnailAsync(ThumbnailMode.SingleItem, 64)
Dim bmp As New BitmapImage()
bmp.SetSource(fileThumbnail)
Dim img As New Image()
img.Source = bmp
Afbeeldingen eenmaal decoderen
Als u wilt voorkomen dat afbeeldingen meer dan één keer worden gedecodeerd, wijst u de eigenschap Image.Source toe vanuit een URI in plaats van geheugenstromen te gebruiken. Het XAML-framework kan dezelfde Uri op meerdere plaatsen koppelen aan één gedecodeerde afbeelding, maar kan niet hetzelfde doen voor meerdere geheugenstromen die dezelfde gegevens bevatten en maakt voor elke geheugenstroom een andere gedecodeerde afbeelding.