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 WinUI-apps met vloeiende animaties, hoge framesnelheid en hoogpresterende media-opname en weergave.
Animaties vloeiend maken
Een belangrijk aspect van WinUI-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 de 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 Het overzicht animaties voor meer informatie over animaties. Zie De UI-thread responsief houden voor 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 naar de eigenschappen Canvas.Left en Canvas.Top
Animaties naar de eigenschap UIElement.Opacity
Animaties naar eigenschappen van het type Brush bij het richten van de SolidColorBrush.Color-subproperty
nl-NL: Animaties voor de volgende UIElement-eigenschappen wanneer subeigenschappen van deze retourwaardetypen worden getarget.
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:
- Stel de eigenschap EnableDependentAnimation in 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 breedte en hoogte van een object. Wees niet bang om objecten zoals afbeeldingen en tekst te schalen. Het framework past bilineaire schaalaanpassing alleen toe terwijl scaleTransform wordt geanimeerd. De afbeelding en tekst worden gerasteriseerd op de uiteindelijke grootte voor optimale helderheid.
- Het maken van updates per frame, die effectief afhankelijke animaties zijn. Een voorbeeld hiervan is het toepassen van transformaties in de handler van de gebeurtenis CompositionTarget.Rendering .
- 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.
Een webweergave2 of MediaPlayerElement niet animeren
Webinhoud die wordt gehost in een WebView2-besturingselement wordt niet rechtstreeks weergegeven door het XAML-framework, dus het opstellen met de rest van de scène vereist extra werk. Deze overhead loopt op wanneer u het besturingselement over het scherm animeert en kan synchronisatieproblemen veroorzaken, bijvoorbeeld als de webinhoud uit de pas lijkt te lopen met de omringende XAML. Als u beweging rond webinhoud nodig hebt, kunt u de omringende WinUI-chrome in plaats van het WebView2-oppervlak zelf animeren. Eerdere richtlijnen kunnen WebViewBrush vermelden; in moderne WinUI-apps is WebView2 de ondersteunde webhostingcontrole, en er is geen directe vervanging van WebViewBrush.
Een mediaplayerelement animeren is een soortgelijk slecht idee. Afgezien van de prestatieschade kan dit leiden tot scheuring of andere artefacten in de video-inhoud die wordt afgespeeld.
Oneindige animaties spaarzaam gebruiken
De meeste animaties worden gedurende een opgegeven tijdsduur uitgevoerd, maar als u de eigenschap Timeline.Duration instelt op Forever, 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 een handler voor deze gebeurtenis dwingt deze om bij elk frame te draaien. Verwijder de handler wanneer er geen werk moet worden gedaan en registreer hem opnieuw wanneer hij weer nodig is.
De animatiebibliotheek gebruiken
De naamruimte Microsoft.UI.Xaml.Media.Animation 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 het overzicht van 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 WinUI-apps te verbeteren.
Opmerking De animatiebibliotheek kan niet alle mogelijke eigenschappen animeren. Voor XAML-scenario's waarin de animatiebibliotheek niet van toepassing is, raadpleegt u Storyboarded-animaties.
Animate CompositeTransform3D-eigenschappen onafhankelijk
U kunt elke eigenschap van een CompositeTransform3D onafhankelijk van animatie voorzien, dus pas alleen de animaties toe die u nodig hebt. Zie UIElement.Transform3D voor voorbeelden en meer informatie. Voor meer informatie over animatietransformaties, zie Storyboards voor animaties en Keyframe- en easingfunctie-animaties.
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 die nodig zijn voor het opslaan, decoderen en afspelen van deze inhoud toe. Het XAML-framework bouwt voort op moderne Windows-media-infrastructuur, zodat WinUI-apps automatisch veel van deze verbeteringen overnemen. Hier volgen enkele extra trucs waarmee u optimaal gebruik kunt maken van media in uw WinUI-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 handle naar de media direct 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 WinUI-apps altijd de eigenschap IsFullWindow op het MediaPlayerElement om volledige weergave van vensters 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ëntste 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 verbergt wanneer ze niet nodig zijn (set Visibility="Collapsed") om het afspelen van media in de meest efficiënte staat terug te zetten.
Het uitschakelen van het scherm en energie besparen
Als u wilt voorkomen dat de weergave wordt gedeactiveerd wanneer gebruikersactie niet meer wordt gedetecteerd, bijvoorbeeld wanneer een app video afspeelt, kunt u DisplayRequest.RequestActive aanroepen.
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. Nu bent u uiteraard de optimalisatie op volledig scherm kwijt, omdat het MediaPlayerElement niet de grootte van de pagina is en er andere XAML-objecten zijn getekend. Pas op dat u deze modus onbedoeld invoert door een rand rond een MediaPlayerElement te 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. MediaPlayerElement wordt gedwongen dit werk uit te voeren nadat de bron is ingesteld via de eigenschap Bron. Dit instellen wanneer de gebruiker echt klaar is om media af te spelen, vertraagt het merendeel van de kosten die zijn gekoppeld aan het MediaPlayerElement zo lang mogelijk.
MediaPlayerElement.PosterSource instellen
Door MediaPlayerElement.PosterSource in te stellen, 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 schuifbalk te wijzigen. Hier volgen enkele tips om dit zo efficiënt mogelijk te maken:
- Werk de waarde van Slider bij op basis van een timer die de positie op het MediaPlayerElement.MediaPlayer opvraagt. Zorg ervoor dat u een redelijke updatefrequentie gebruikt voor uw timer. De eigenschap Position werkt alleen elke 250 milliseconden bij tijdens het afspelen.
- De grootte van de stapgrootte op de schuifregelaar moet meeschalen met de lengte van de video.
- Abonneer u op de gebeurtenissen PointerPressed, PointerMoved, PointerReleased 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 schuifregelaarpositiewaarde voor optimale duimvastklikken tijdens het schrobben.
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 de prestaties van de Windows App SDK raden we H.264-video aan als de 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 offload van hardware in volledige stroom (dat wil wel de 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 u korte audio-effecten met lage latentie, bijvoorbeeld in games, gebruikt u WAV-bestanden met niet-gecomprimeerde PCM-gegevens om de verwerkingsoverhead te verminderen die gebruikelijk is voor gecomprimeerde audio-indelingen.
Afbeeldingsbronnen optimaliseren
Afbeeldingen schalen naar de juiste grootte
Afbeeldingen worden vastgelegd bij zeer hoge resoluties, wat ertoe kan leiden dat apps meer CPU gebruiken bij het decoderen van de afbeeldingsgegevens en meer geheugen verbruiken nadat deze 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 waarop deze op het scherm getekend wordt 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: DecodePixelType instellen op Logical zorgt ervoor dat de decodeergrootte automatisch rekening houdt met de huidige schaalfactor van het systeem, vergelijkbaar met andere XAML-inhoud. Het is daarom over het algemeen geschikt om Decode PixelType in te stellen op Logisch als u bijvoorbeeld Decode PixelWidth en Decode PixelHeight wilt afstemmen op de eigenschappen Hoogte en Breedte van het besturingselement 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 zijn dan waar de afbeelding op het scherm wordt weergegeven, wordt deze vergroot en kan pixelachtig lijken.
In sommige gevallen waarin een geschikte decodegrootte niet van tevoren kan worden bepaald, moet u vertrouwen op de automatische juistformaatdecodering van XAML, die zal proberen de afbeelding op de juiste grootte te decoderen als er geen expliciete DecodePixelWidth/DecodePixelHeight 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 Logisch 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 dimensies
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.
- BitmapImage is verbonden met de live XAML-structuur na het instellen van de inhoud met SetSourceAsync of UriSource.
- De afbeelding wordt gedecodeerd met synchrone decodering, zoals SetSource.
- De afbeelding is verborgen door Opaciteit op 0 te zetten of de Zichtbaarheid op Ingeklapt te zetten op het hostafbeeldingselement, penseel of een ander bovenliggend element.
- Het besturingselement of de kwast van de afbeelding maakt gebruik van een Stretch of None.
- De afbeelding wordt gebruikt als een NineGrid.
-
CacheMode="BitmapCache"is ingesteld op de afbeelding 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 livestructuur koppelen voordat u de bron instelt. Telkens wanneer een afbeeldingselement of penseel wordt opgegeven in markeringen, is dit automatisch het geval. Hieronder ziet u voorbeelden onder de koptekst 'Voorbeelden van leefboom'. Vermijd het gebruik van SetSource en gebruik in plaats daarvan SetSourceAsync bij het instellen van een stroombron. En het is een goed idee om te voorkomen dat afbeeldingsinhoud wordt verborgen (met nul dekking of met samengevouwen zichtbaarheid) terwijl u wacht totdat de gebeurtenis ImageOpened wordt gegenereerd. Dit is een beoordelingskwestie: u profiteert niet van automatische decodering die zich aanpast aan de juiste grootte als u dat doet. Als uw app in eerste instantie afbeeldingsinhoud moet verbergen, moet deze ook de grootte van de decoderen expliciet instellen, indien mogelijk.
Voorbeelden van interactieve boomstructuren
Voorbeeld 1 (goed): URI (Uniform Resource Identifier) die is opgegeven in markeringen.
<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>
Voorbeeld 2 markup—URI opgegeven in code-behind.
<Image x:Name="myImage"/>
Voorbeeld 2 code-behind (goed): verbind de BitmapImage met de boomstructuur voordat de UriSource wordt ingesteld.
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 BitmapImage instellen voordat deze verbinding maakt 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
Caching-optimalisaties 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 afbeelding op, en als XAML geen afbeelding met een bron-URI kan vinden die overeenkomt met de vereiste resolutie, wordt een nieuwe versie gedecodeerd tot die grootte. De gecodeerde afbeeldingsgegevens worden echter niet opnieuw gedownload.
Daarom moet u UriSource gebruiken bij het laden van afbeeldingen uit een app-pakket en vermijd een bestandsstroom en SetSourceAsync te gebruiken wanneer dit niet vereist is.
Afbeeldingen in gevirtualiseerde panelen (bijvoorbeeld ListView)
Als een afbeelding uit de structuur wordt verwijderd omdat de app deze expliciet heeft verwijderd, of omdat deze zich in een modern gevirtualiseerd paneel bevindt en impliciet werd verwijderd bij het uit beeld scrollen, optimaliseert XAML het geheugengebruik door de hardwarebronnen voor de afbeelding vrij te geven, aangezien ze niet meer nodig zijn. Het geheugen wordt niet onmiddellijk vrijgegeven, maar wordt in plaats daarvan vrijgegeven tijdens de frame-update die plaatsvindt wanneer het afbeeldingselement al één seconde niet meer in de boomstructuur zit.
Daarom moet u ernaar streven om moderne gevirtualiseerde panelen te gebruiken om lijsten met afbeeldingsinhoud te hosten.
Software-rasterafbeeldingen
Wanneer een afbeelding wordt gebruikt voor een niet-rechthoekig penseel of voor een NineGrid, gebruikt de afbeelding een pad voor softwarerastering, waardoor afbeeldingen helemaal niet worden geschaald. Daarnaast moet een kopie van de afbeelding worden opgeslagen in zowel het software- als het harde geheugen. 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 image-element of op een ouder-element. - Het afbeeldingsborstel is niet rechthoekig (bijvoorbeeld wanneer deze wordt toegepast op een vorm of op tekst).
SoftwareBitmapSource
De Klasse SoftwareBitmapSource wisselt interoperabele niet-gecomprimeerde afbeeldingen uit tussen verschillende WinRT-naamruimten, zoals BitmapDecoder, camera-API's en XAML. Deze klasse voorkomt een extra kopie die doorgaans nodig zou zijn met WriteableBitmap, wat helpt om piekgeheugen- en bron-naar-schermlatentie te verminderen.
De SoftwareBitmap die brongegevens levert, kan ook worden geconfigureerd voor het gebruik van een aangepaste IWICBitmap om een herlaadbare back-upopslag te bieden waarmee de app geheugen opnieuw kan toewijzen naar wens. Dit is een geavanceerde C++-use case.
Uw app moet SoftwareBitmap en SoftwareBitmapSource gebruiken 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 WriteableBitmap te 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 Windows nog efficiëntere API's voor het ophalen van miniaturen. GetThumbnailAsync biedt de miniaturen voor afbeeldingen waarvan het bestandssysteem al in de cache is opgeslagen. Dit biedt nog betere prestaties dan de XAML-API's, omdat de afbeelding niet hoeft te worden geopend of gedecodeerd.
Initialiseer in een Windows App SDK-app de kiezer met de venstergreep van uw app, bijvoorbeeld door het hoofdvenster op te slaan als App.MainWindow.
FileOpenPicker picker = new FileOpenPicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
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();
await bmp.SetSourceAsync(fileThumbnail);
Image img = 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 geheugenstreams te gebruiken. Het XAML-framework kan dezelfde URI op meerdere plaatsen koppelen aan één gedecodeerde afbeelding, maar kan hetzelfde niet doen voor meerdere geheugenstromen die dezelfde gegevens bevatten en creëert voor elke geheugenstroom een andere gedecodeerde afbeelding.
Windows developer