Sdílet prostřednictvím


Optimalizace animací, médií a obrázků

Vytvářejte aplikace univerzální platformy Windows (UPW) s hladkými animacemi, vysokou frekvencí snímků a vysoce výkonným zachytáváním a přehráváním médií.

Zajistěte plynulost animací

Klíčovým aspektem aplikací pro UPW je hladké interakce. To zahrnuje manipulace s dotykovým ovládáním, které se "drží prstem", hladké přechody a animace a malé pohyby, které poskytují zpětnou vazbu. V rozhraní XAML existuje vlákno označované jako vlákno složení, které je vyhrazené pro složení a animaci vizuálních prvků aplikace. Vzhledem k tomu, že vlákno složení je oddělené od vlákna uživatelského rozhraní (vlákno, které spouští architekturu a kód pro vývojáře), můžou aplikace dosáhnout konzistentní frekvence snímků a hladkých animací bez ohledu na složité průchody rozložení nebo rozšířené výpočty. V této části se dozvíte, jak pomocí kompozičního vlákna udržet animace aplikace dokonale plynulé. Další informace o animacích najdete v tématu Přehled animací. Další informace o zvýšení rychlosti odezvy aplikace při provádění náročných výpočtů najdete v tématu Zachování odezvy vlákna uživatelského rozhraní.

Použijte nezávislé místo závislých animací

Nezávislé animace se dají vypočítat od začátku do konce v době vytváření, protože změny animace vlastnosti nemají vliv na zbytek objektů ve scéně. Nezávislé animace se proto můžou spouštět ve vlákně složení místo vlákna uživatelského rozhraní. To zaručuje, že zůstanou hladké, protože se kompoziční vlákno aktualizuje konzistentním tempem.

U všech těchto typů animací je zaručeno, že budou nezávislé:

Závislé animace ovlivňují rozložení, které proto nelze vypočítat bez dodatečného vstupu z vlákna uživatelského rozhraní. Závislé animace zahrnují úpravy vlastností, jako je Šířka a Výška. Ve výchozím nastavení nejsou závislé animace spuštěné a vyžadují výslovný souhlas od vývojáře aplikací. Pokud je povoleno, běží hladce, pokud vlákno uživatelského rozhraní zůstane odblokované; ale začnou se zadrhávat, pokud architektura nebo aplikace vykonává mnoho dalších úloh na vlákně uživatelského rozhraní.

Téměř všechny animace v rámci XAML jsou ve výchozím nastavení nezávislé, ale existuje několik akcí, které můžete provést, abyste tuto optimalizaci zakázali. Dávejte pozor zejména na tyto scénáře:

  • Nastavením vlastnosti EnableDependentAnimation povolit spuštění závislé animace ve vlákně uživatelského rozhraní. Převeďte tyto animace na nezávislou verzi. Například animujte ScaleTransform.ScaleX a ScaleTransform.ScaleY místo šířky a výšky objektu. Nebojte se škálovat objekty, jako jsou obrázky a text. Architektura používá bilineární škálování pouze v době, kdy se ScaleTransform animuje. Obrázek/text se přerastruje na konečnou velikost, aby se zajistilo, že bude vždy čistý.
  • Provádění aktualizací jednotlivých snímků, což jsou efektivně závislé animace. Příkladem je použití transformací v obslužné rutině CompositonTarget.Rendering události.
  • Spuštění jakékoliv animace, která je považována za nezávislou, v prvku s vlastností CacheMode nastavenou na BitmapCache. To je považováno za závislé, protože mezipaměť musí být pro každý snímek znovu rasterizována.

Neanimujte WebView ani MediaPlayerElement

Webový obsah v rámci Ovládací prvek WebView není přímo vykreslen rozhraním XAML a vyžaduje další práci, která se skládá se zbytkem scény. Tato nadbytečná práce se zvyšuje při animaci ovládacího prvku po obrazovce a může potenciálně nastat problémy se synchronizací (například obsah HTML se nemusí synchronizovat se zbytkem obsahu XAML na stránce). Když potřebujete animovat ovládací prvek WebView, prohoďte jej za WebViewBrush po dobu trvání animace.

Animace MediaPlayerElement je podobně špatný nápad. Kromě negativního dopadu na výkon může docházet k roztrhání obrazu nebo jiným artefaktům v přehrávaném videu.

Poznámka Doporučení v tomto článku pro MediaPlayerElement platí také pro MediaElement. MediaPlayerElement je k dispozici pouze ve Windows 10 verze 1607, takže pokud vytváříte aplikaci pro předchozí verzi Windows, musíte použít MediaElement.

Použití nekonečných animací střídmě

Většina animací se spouští po určitou dobu, ale nastavení vlastnosti Timeline.Duration na hodnotu Forever umožňuje, aby se animace běžela neomezeně dlouho. Doporučujeme minimalizovat použití nekonečných animací, protože neustále spotřebovávají prostředky procesoru a můžou zabránit tomu, aby procesor přešel do nízkého výkonu nebo nečinného stavu, což by mohlo způsobit rychlejší výpadky výkonu.

Přidání handleru pro CompositionTarget.Rendering je podobné spuštění nekonečné animace. Obvykle je vlákno uživatelského rozhraní aktivní pouze v případě, že je k dispozici práce, ale přidání obslužné rutiny pro tuto událost vynutí, aby se spustil každý rámec. Odeberte obslužnou rutinu, když není třeba žádná práce, a znovu ji registrujte, až bude opět potřeba.

Použití knihovny animací

Obor názvů Windows.UI.Xaml.Media.Animation obsahuje knihovnu vysoce výkonných, hladkých animací, které mají vzhled a chování konzistentní s ostatními animacemi Windows. Příslušné třídy mají ve svém názvu "Motiv" a jsou popsány v Přehledu Animace. Tato knihovna podporuje řadu běžných animačních scénářů, jako je animace prvního zobrazení aplikace a vytváření přechodů stavu a obsahu. Tuto animační knihovnu doporučujeme používat, kdykoli je to možné, abyste zvýšili výkon a konzistenci uživatelského rozhraní UPW.

Poznámka Knihovna animací nemůže animovat všechny možné vlastnosti. Pro scénáře XAML, kde se knihovna animací nepoužívá, viz animace s předpřipraveným scénářem.

Animujte vlastnosti CompositeTransform3D nezávisle na sobě

Jednotlivé vlastnosti CompositeTransform3D můžete animovat nezávisle, takže použijte jenom animace, které potřebujete. Příklady a další informace najdete v tématu UIElement.Transform3D. Další informace o animaci transformací najdete v tématu animace s příběhem a animace s klíčovým snímkem a funkcí pro usnadnění.

Optimalizace mediálních prostředků

Zvukové, video a obrázky jsou poutavé formy obsahu, které většina aplikací používá. S tím, jak se míra zachytávání médií zvyšuje a obsah se přesouvá ze standardní definice na vysokou definici, zvyšuje se množství prostředků potřebných k ukládání, dekódování a přehrávání tohoto obsahu. Architektura XAML vychází z nejnovějších funkcí přidaných do mediálních modulů UPW, aby aplikace získaly tato vylepšení zdarma. Tady si vysvětlíme některé další triky, které vám umožní získat v aplikaci UPW maximum z médií.

Uvolnit datové proudy médií

Mediální soubory jsou některé z nejběžnějších a nejnákladnějších zdrojů, které aplikace obvykle používají. Vzhledem k tomu, že prostředky multimediálních souborů můžou výrazně zvětšit velikost paměti aplikace, nezapomeňte uvolnit popisovač k médiu, jakmile aplikace dokončí jeho použití.

Pokud například vaše aplikace pracuje s objektem RandomAccessStream nebo objektem IInputStream, nezapomeňte zavolat metodu close na objektu poté, co vaše aplikace dokončí jeho používání, aby se uvolnil podkladový objekt.

Zobrazení přehrávání videa na celé obrazovce, pokud je to možné

V aplikacích pro UWP vždy použijte vlastnost IsFullWindow na MediaPlayerElement k povolení a zakázání zobrazení na celou obrazovku. Toto zajišťuje, že optimalizace na úrovni systému jsou používány při přehrávání médií.

Architektura XAML může optimalizovat zobrazení video obsahu, když je to jediný prvek, který se vykresluje, což vede k menší spotřebě energie a vyšší frekvenci snímkování. Pro nejúčinnější přehrávání médií nastavte velikost MediaPlayerElement tak, aby se rovnala šířce a výšce obrazovky, a nezobrazujte ostatní prvky XAML.

Existují oprávněné důvody překrytí elementů XAML na MediaPlayerElement, které zabírají plnou šířku a výšku obrazovky, například skryté titulky nebo dočasné ovládací prvky přehrávače. Tyto prvky (nastavené Visibility="Collapsed") nezapomeňte skrýt, pokud nejsou potřeba k přehrání médií zpět do nejúčinnějšího stavu.

Deaktivace displeje a úspora energie

Pokud chcete zabránit deaktivaci zobrazení, když se už nezjistí akce uživatele, například při přehrávání videa aplikace, můžete volat DisplayRequest.RequestActive.

Pokud chcete ušetřit energii a výdrž baterie, měli byste zavolat DisplayRequest.RequestRelease, aby se žádost o zobrazení uvolnila, jakmile už ji nepotřebujete.

Tady je několik situací, kdy byste měli vydat žádost o zobrazení:

  • Přehrávání videa je pozastaveno, například akcí uživatele, ukládáním do vyrovnávací paměti nebo úpravou kvůli omezené šířce pásma.
  • Přehrávání se zastaví. Video se například přestalo přehrávat, nebo prezentace skončila.
  • Došlo k chybě přehrávání. Například problémy s připojením k síti nebo poškozený soubor.

Umístěte další prvky na stranu vloženého videa.

Aplikace často nabízejí vložené zobrazení, ve kterém se video přehrávala na stránce. Nyní jste zřejmě ztratili optimalizaci pro celou obrazovku, protože MediaPlayerElement není ve velikosti stránky a jsou vykresleny další objekty XAML. Dávejte pozor na neúmyslné vstupování do tohoto režimu nakreslením okraje kolem MediaPlayerElement.

Nevykreslujte prvky XAML nad videem, když jsou v integrovaném režimu. Pokud to uděláte, rámec je nucen vykonat trochu více práce pro sestavení scény. Umístění ovládacích prvků přenosu pod vložený mediální prvek namísto nad video je dobrým příkladem optimalizace pro tuto situaci. Na tomto obrázku červený pruh označuje sadu ovládacích prvků přenosu (přehrávání, pozastavení, zastavení atd.).

MediaPlayerElement s překryvnými prvky

Tyto ovládací prvky neumisťujte na médium, které není na celé obrazovce. Místo toho umístěte ovládací prvky přenosu někam mimo oblast, kde se médium vykresluje. Na dalším obrázku se ovládací prvky umístí pod médium.

MediaPlayerElement se sousedními prvky

Zpoždění nastavení zdroje pro MediaPlayerElement

Mediální enginy jsou nákladné objekty a architektura XAML zpožďuje načítání DLL knihoven a vytváření velkých objektů co nejdéle. MediaPlayerElement je nucen provést tuto práci poté, co je nastavena jeho zdrojová vlastnost prostřednictvím Source. Nastavení této hodnoty, když je uživatel skutečně připraven přehrávat média, odsouvá většinu nákladů spojených s MediaPlayerElement co nejdéle.

Nastavení MediaPlayerElement.PosterSource

Nastavení MediaPlayerElement.PosterSource umožňuje XAML uvolnit některé prostředky GPU, které by jinak byly použity. Toto rozhraní API umožňuje aplikaci používat co nejmenší paměť.

Vylepšení čištění médií

Scrubbing je vždy náročným úkolem pro mediální platformy, aby skutečně dobře fungovaly. Lidé toho obvykle dosahují změnou hodnoty posuvníku. Tady je několik tipů, jak tento postup co nejefektivněji zajistit:

  • Aktualizujte hodnotu posuvníku podle časovače, který dotazuje pozici na v MediaPlayerElement.MediaPlayer. Ujistěte se, že pro časovač používáte přiměřenou frekvenci aktualizací. Vlastnost Position aktualizuje při přehrávání pouze každých 250 milisekund.
  • Velikost frekvence kroku na posuvníku se musí škálovat s délkou videa.
  • Přihlaste se k odběru PointerPressed, PointerMoveda PointerReleased událostí na posuvníku a nastavte vlastnost PlaybackRate na hodnotu 0, když uživatel přetáhne jezdec posuvníku.
  • V obslužné rutině události PointerReleased ručně nastavte pozici přehrávání média na hodnotu pozice posuvníku, abyste dosáhli optimálního posunu palce při posouvání.

Porovnání rozlišení videa s rozlišením zařízení

Dekódování videa trvá hodně paměti a cyklů GPU, takže zvolte formát videa blízko rozlišení, na kterém se zobrazí. Použití výpočetních prostředků k dekódování 1080p videa nemá smysl, pokud bude následně přeškálováno na mnohem menší velikost. Mnoho aplikací nemá stejné video kódované v různých rozlišeních; ale pokud je k dispozici, použijte kódování, které je blízko rozlišení, ve kterém se zobrazí.

Výběr formátu médií může být citlivým tématem a často se řídí obchodními rozhodnutími. Z hlediska výkonu UPW doporučujeme video H.264 jako primární formát videa a AAC a MP3 jako upřednostňované formáty zvuku. Pro přehrávání místních souborů je mp4 upřednostňovaným kontejnerem souborů pro videoobsáh. Dekódování H.264 se akceleruje prostřednictvím nejnovějšího grafického hardwaru. Ačkoli je hardwarová akcelerace pro dekódování VC-1 široce dostupná, pro velkou řadu grafických zařízení na trhu je akcelerace v mnoha případech omezena na částečnou úroveň akcelerace (nebo úroveň IDCT), a nikoli na kompletní hardwarové odlehčení (tj. režim VLD).

Pokud máte úplnou kontrolu nad procesem generování obsahu videa, musíte zjistit, jak zajistit dobrou rovnováhu mezi efektivitou komprese a strukturou GOP. Relativně menší velikost GOP s B snímky může zlepšit výkon při hledání nebo trikových režimech.

Pokud zahrnete krátké zvukové efekty s nízkou latencí, například ve hrách, používejte soubory WAV s nekomprimovanými daty PCM, abyste snížili režii zpracování, která je typická pro komprimované formáty zvuku.

Optimalizace obrazových prostředků

Škálování obrázků na odpovídající velikost

Obrázky se zaznamenávají ve velmi vysokém rozlišení, což může vést k tomu, že aplikace při dekódování dat obrázku a více paměti po načtení z disku využívají více procesoru. Nedává smysl dekódovat a uložit obrázek s vysokým rozlišením do paměti, pokud ho pak zobrazíte v menším rozměru, než je jeho původní velikost. Místo toho vytvořte verzi obrázku s přesnou velikostí, na které se bude kreslit na obrazovce, pomocí vlastností DecodePixelWidth a DecodePixelHeight.

Nedělejte toto:

<Image Source="ms-appx:///Assets/highresCar.jpg"
       Width="300" Height="200"/>    <!-- BAD CODE DO NOT USE.-->

Místo toho postupujte takto:

<Image>
    <Image.Source>
    <BitmapImage UriSource="ms-appx:///Assets/highresCar.jpg"
                 DecodePixelWidth="300" DecodePixelHeight="200"/>
    </Image.Source>
</Image>

Jednotky pro DecodePixelWidth a DecodePixelHeight jsou ve výchozím nastavení fyzické pixely. Vlastnost DecodePixelType lze použít ke změně tohoto chování: nastavení DecodePixelType na Logické vede k automatickému účtování velikosti dekódování aktuálního faktoru škálování systému, podobně jako u jiného obsahu XAML. Proto by bylo obecně vhodné nastavit DecodePixelType na Logical, pokud například chcete, aby DecodePixelWidth a DecodePixelHeight odpovídaly vlastnostem výšky a šířky ovládacího prvku Image, ve kterém bude obrázek zobrazen. Pokud aplikace standardně používá fyzické pixely, musíte sami zohlednit aktuální měřítko systému a měli byste pravidelně kontrolovat oznámení o změnách škálování pro případ, že uživatel změní předvolby zobrazení.

Pokud je decodePixelWidth/Height explicitně nastavená větší než obrázek, aplikace zbytečně využije další paměť ( až 4 bajty na pixel), což je pro velké obrázky rychle nákladné. Obrázek se také zmenší pomocí bilineárního škálování, což by mohlo způsobit, že při velkých faktorech škálování bude vypadat rozmazaně.

Pokud jsou DecodePixelWidth/DecodePixelHeight explicitně nastaveny na menší hodnoty, než jak bude obrázek zobrazen na obrazovce, bude zvětšen a může vypadat pixelově.

V případech, kdy nelze předem určit vhodnou velikost dekódování, byste měli využít automatické dekódování XAML, které se pokusí co nejlépe dekódovat obraz na odpovídající velikost, pokud není zadán explicitní DecodePixelWidth/DecodePixelHeight.

Pokud znáte velikost obsahu obrázku předem, měli byste nastavit explicitní dekódovací velikost. Měli byste také v kombinaci nastavit DecodePixelType na logické, pokud je zadaná velikost dekódování relativní k jiným velikostem elementů XAML. Pokud například explicitně nastavíte velikost obsahu s hodnotou Image.Width a Image.Height, můžete DecodePixelType nastavit na DecodePixelType.Logical tak, aby se používaly stejné logické pixelové rozměry jako ovládací prvek Obrázek, a pak explicitně použít BitmapImage.DecodePixelWidth a/nebo BitmapImage.DecodePixelHeight k řízení velikosti obrázku, aby se dosáhlo potenciálně velkých úspor paměti.

Všimněte si, že Při určování velikosti dekódovaného obsahu by se měla zvážit možnost Image.Stretch.

Dekódování správné velikosti

V případě, že nenastavíte explicitní dekódovací velikost, xaml se pokusí uložit paměť dekódováním obrázku na přesnou velikost, která se zobrazí na obrazovce podle počátečního rozložení stránky. Doporučujeme, abyste aplikaci napsali takovým způsobem, jak tuto funkci používat, pokud je to možné. Tato funkce bude zakázána, pokud jsou splněny některé z následujících podmínek.

  • BitmapImage je po nastavení obsahu pomocí SetSourceAsync nebo UriSourcepřipojen k živému stromu XAML.
  • Obrázek je dekódován pomocí synchronního dekódování, jako je SetSource.
  • Obrázek je skrytý prostřednictvím nastavení Neprůhlednost na 0 nebo Viditelnost na Sbalení na hostitelském prvku obrázku, štětci nebo jakémkoliv nadřazeném prvku.
  • Ovládací prvek obrázku nebo štětec používá StretchNone.
  • Image se používá jako NineGrid.
  • CacheMode="BitmapCache" je nastaven na obrázkový element nebo jakémkoli nadřazeném elementu.
  • Obrázkový štětec není obdélníkový (například při použití na obrazec nebo na text).

Ve výše uvedených scénářích je nastavení explicitní velikosti dekódování jediným způsobem, jak dosáhnout úspor paměti.

Před nastavením zdroje byste vždy měli k živému stromu připojit BitmapImage. Pokaždé, když je prvek obrázku nebo štětec zadán v kódu, bude to automaticky případ. Příklady jsou uvedeny níže pod nadpisem "Příklady živého stromu". Vždy byste se měli vyhnout použití SetSource a místo toho použít SetSourceAsync při nastavování zdroje datového proudu. Je dobrý nápad vyhnout se skrývání obsahu obrázku (buď s nulovou neprůhledností, nebo se sbalenou viditelností) při čekání na vyvolání události ImageOpened. Toto je otázka úsudku: Pokud je to hotové, nebudete mít prospěch z automatického dekódování odpovídající velikosti. Pokud vaše aplikace musí zpočátku skrýt obsah obrázku, měla by také nastavit velikost dekódování explicitně, pokud je to možné.

Příklady živých stromů

Příklad 1 (dobrý) – identifikátor URI (Uniform Resource Identifier) zadaný v kódu

<Image x:Name="myImage" UriSource="Assets/cool-image.png"/>

Příklad 2 kódu značkování – URI specifikováno v kódu na pozadí.

<Image x:Name="myImage"/>

Příklad 2 vnitřního kódu (dobrý) – připojení BitmapImage ke stromu před nastavením jeho Uri zdroje.

var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);

Příklad 2 v zákulisí kódu (špatný) – nastavování UriSource BitmapImage před připojením ke stromu.

var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///Assets/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;

Optimalizace ukládání do mezipaměti

Optimalizace ukládání do mezipaměti platí pro obrázky, které používají UriSource k načtení obsahu z balíčku aplikace nebo z webu. Identifikátor URI se používá k jedinečné identifikaci podkladového obsahu a interně architektura XAML nebude stahovat ani dekódovat obsah vícekrát. Místo toho bude k zobrazení obsahu vícekrát používat software nebo hardwarové prostředky uložené v mezipaměti.

Výjimkou této optimalizace je, že se obrázek zobrazuje několikrát v různých rozlišeních (které je možné explicitně zadat nebo prostřednictvím automatického dekódování správné velikosti). Každá položka mezipaměti také ukládá rozlišení obrázku a pokud XAML nemůže najít obrázek se zdrojovým identifikátorem URI, který odpovídá požadovanému rozlišení, dekóduje novou verzi s danou velikostí. Nebudou však znovu stahovat zakódovaná data obrázků.

V důsledku toho byste při načítání obrázků z balíčku aplikace měli použít UriSource a vyhnout se použití streamu souborů a SetSourceAsync, pokud to není nutné.

Obrázky na virtualizovaných panelech (například ListView)

Pokud je obrázek ze stromu odebrán, protože jej aplikace explicitně odebrala, nebo protože je na moderním virtualizovaném panelu a byl implicitně odebrán, když se posune mimo zobrazení, XAML optimalizuje využití paměti uvolněním hardwarových prostředků pro obrázek, protože už nejsou potřeba. Paměť není uvolněna okamžitě, ale až při aktualizaci rámce, která proběhne po jedné sekundě poté, co prvek obrázku již není ve stromu.

V důsledku toho byste se měli snažit používat moderní virtualizované panely k hostování seznamů obsahu obrázků.

Softwarově rasterizované obrázky

Pokud se obrázek používá pro neobdélníkový štětec nebo pro NineGrid, obrázek bude používat softwarovou rasterizační cestu, která nebude škálovat obrázky vůbec. Kromě toho musí uložit kopii image do softwarové i hardwarové paměti. Pokud se například obrázek použije jako štětec pro elipsu, celý potenciálně velký obrázek se uloží dvakrát interně. Pokud používáte NineGrid nebo neobdélníkový štětec, měla by vaše aplikace předem škálovat obrázky na přibližnou velikost, na kterou se budou vykreslovat.

Načítání obrázků na pozadí ve vláknu

XAML má interní optimalizaci, která umožňuje dekódovat obsah obrázku asynchronně na povrch v hardwarové paměti, aniž by vyžadoval zprostředkující povrch v softwarové paměti. Tím se snižuje využití paměti ve špičce a latence vykreslování. Tato funkce bude zakázána, pokud jsou splněny některé z následujících podmínek.

  • Image se používá jako NineGrid.
  • CacheMode="BitmapCache" je nastaven na obrázkový element nebo jakémkoli nadřazeném elementu.
  • Obrázkový štětec není obdélníkový (například při použití na obrazec nebo na text).

SoftwareBitmapSource

SoftwareBitmapSource třída vyměňuje interoperabilní nekomprimované obrázky mezi různými obory názvů WinRT, jako jsou BitmapDecoder, rozhraní API fotoaparátu a XAML. Tato třída eliminuje potřebu dodatečné kopie, která by obvykle byla nutná s WriteableBitmap, a pomáhá snížit špičkové využití paměti a latenci mezi zdrojem a obrazovkou.

SoftwareBitmap, která poskytuje informace o zdroji, lze také nakonfigurovat tak, aby používala vlastní IWICBitmap k zajištění znovu načitatelného úložiště, které aplikaci umožňuje namapovat paměť podle potřeby. Jedná se o pokročilý případ použití jazyka C++.

Aplikace by měla používat SoftwareBitmap a SoftwareBitmapSource pro spolupráci s jinými rozhraními API WinRT, která vytvářejí a využívají image. Aplikace by měla používat SoftwareBitmapSource při načítání nekomprimovaných dat obrázků místo použití WriteableBitmap.

Použití metody GetThumbnailAsync pro miniatury

Jedním z případů použití pro škálování obrázků je vytváření miniatur. I když byste mohli použít DecodePixelWidth a DecodePixelHeight k poskytování malých verzí obrázků, UPW poskytuje ještě efektivnější rozhraní API pro načítání miniatur. GetThumbnailAsync poskytuje miniatury obrázků, které už mají systém souborů uložený v mezipaměti. To poskytuje ještě lepší výkon než rozhraní API XAML, protože image nemusí být otevřená ani dekódována.

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

Obrázky dekódovat jednou

Pokud chcete zabránit dekódování obrázků více než jednou, přiřaďte vlastnost Image.Source identifikátoru URI místo použití datových proudů paměti. Architektura XAML může přidružit stejný identifikátor URI na více místech k jedné dekódované imagi, ale nemůže provést totéž pro více datových proudů paměti, které obsahují stejná data, a vytvoří pro každý datový proud paměti jinou dekódovanou image.