Mengoptimalkan animasi, media, dan gambar

Buat aplikasi Platform Windows Universal (UWP) dengan animasi halus, kecepatan bingkai tinggi, dan pengambilan dan pemutaran media berkinerja tinggi.

Membuat animasi menjadi halus

Aspek utama aplikasi UWP adalah interaksi yang lancar. Ini termasuk manipulasi sentuh yang "menempel pada jari Anda," transisi dan animasi halus, dan gerakan kecil yang memberikan umpan balik input. Dalam kerangka kerja XAML ada utas yang disebut utas komposisi yang didedikasikan untuk komposisi dan animasi elemen visual aplikasi. Karena utas komposisi terpisah dari utas UI (utas yang menjalankan kerangka kerja dan kode pengembang), aplikasi dapat mencapai kecepatan bingkai yang konsisten dan animasi yang lancar terlepas dari kode tata letak yang rumit atau perhitungan yang diperluas. Bagian ini menunjukkan cara menggunakan utas komposisi untuk menjaga animasi aplikasi tetap halus. Untuk informasi selengkapnya tentang animasi, lihat Gambaran umum Animasi. Untuk mempelajari tentang meningkatkan responsivitas aplikasi saat melakukan komputasi intensif, lihat Menjaga utas UI tetap responsif.

Gunakan animasi independen alih-alih dependen

Animasi independen dapat dihitung dari awal hingga akhir pada saat pembuatan karena perubahan pada properti yang dianimasikan tidak memengaruhi sisa objek dalam adegan. Oleh karena itu, animasi independen dapat berjalan pada utas komposisi alih-alih utas UI. Ini menjamin bahwa mereka tetap lancar karena utas komposisi diperbarui pada irama yang konsisten.

Semua jenis animasi ini dijamin independen:

Animasi dependen memengaruhi tata letak, yang oleh karena itu tidak dapat dihitung tanpa input tambahan dari utas UI. Animasi dependen mencakup modifikasi pada properti seperti Lebar dan Tinggi. Secara default, animasi dependen tidak dijalankan dan memerlukan keikutsertaan dari pengembang aplikasi. Saat diaktifkan, mereka berjalan dengan lancar jika utas UI tetap tidak diblokir, tetapi mereka mulai gagap jika kerangka kerja atau aplikasi melakukan banyak pekerjaan lain di utas UI.

Hampir semua animasi dalam kerangka kerja XAML independen secara default, tetapi ada beberapa tindakan yang dapat Anda ambil untuk menonaktifkan pengoptimalan ini. Waspadalah terhadap skenario ini terutama:

  • Mengatur properti EnableDependentAnimation untuk memungkinkan animasi dependen berjalan pada utas UI. Konversikan animasi ini menjadi versi independen. Misalnya animasikan ScaleTransform.ScaleX dan ScaleTransform.ScaleY alih-alih Lebar dan Tinggi objek. Jangan takut untuk menskalakan objek seperti gambar dan teks. Kerangka kerja hanya menerapkan penskalaan bilinear saat ScaleTransform sedang dianimasikan. Gambar/teks akan diraster ulang pada ukuran akhir untuk memastikannya selalu jelas.
  • Membuat pembaruan per bingkai, yang secara efektif bergantung pada animasi. Contohnya adalah menerapkan transformasi di handler peristiwa CompositonTarget.Rendering .
  • Menjalankan animasi apa pun yang dianggap independen dalam elemen dengan properti CacheMode diatur ke BitmapCache. Ini dianggap dependen karena cache harus diraster ulang untuk setiap bingkai.

Jangan animasikan WebView atau MediaPlayerElement

Konten web dalam kontrol WebView tidak secara langsung dirender oleh kerangka kerja XAML dan memerlukan pekerjaan ekstra untuk disusam dengan adegan lainnya. Pekerjaan ekstra ini bertambah saat menganimasikan kontrol di sekitar layar dan berpotensi menimbulkan masalah sinkronisasi (misalnya, konten HTML mungkin tidak bergerak sinkron dengan konten XAML lainnya di halaman). Saat Anda perlu menganimasikan kontrol WebView , tukar dengan WebViewBrush selama durasi animasi.

Menganimasikan MediaPlayerElement adalah ide yang sama buruknya. Di luar performa yang merugikan, itu dapat menyebabkan merobek atau artefak lain dalam konten video yang diputar.

Catatan Rekomendasi dalam artikel ini untuk MediaPlayerElement juga berlaku untuk MediaElement. MediaPlayerElement hanya tersedia di Windows 10, versi 1607, jadi jika Anda membuat aplikasi untuk versi Windows sebelumnya, Anda perlu menggunakan MediaElement.

Gunakan animasi tak terbatas dengan hemat

Sebagian besar animasi dijalankan untuk jumlah waktu tertentu, tetapi mengatur properti Timeline.Duration ke Selamanya memungkinkan animasi berjalan tanpa batas waktu. Sebaiknya minimalkan penggunaan animasi tak terbatas karena terus mengonsumsi sumber daya CPU dan dapat mencegah CPU masuk ke status daya rendah atau menganggur, menyebabkan kehabisan daya dengan lebih cepat.

Menambahkan handler untuk CompositionTarget.Rendering mirip dengan menjalankan animasi tak terbatas. Biasanya utas UI hanya aktif ketika ada pekerjaan yang harus dilakukan, tetapi menambahkan handler untuk peristiwa ini memaksanya menjalankan setiap bingkai. Hapus handler ketika tidak ada pekerjaan yang harus dilakukan dan daftarkan ulang ketika diperlukan lagi.

Menggunakan pustaka animasi

Namespace Windows.UI.Xaml.Media.Animation mencakup pustaka animasi berkinerja tinggi dan halus yang memiliki tampilan dan nuansa konsisten dengan animasi Windows lainnya. Kelas yang relevan memiliki "Tema" dalam namanya, dan dijelaskan dalam gambaran umum Animasi. Pustaka ini mendukung banyak skenario animasi umum, seperti menganimasikan tampilan pertama aplikasi dan membuat transisi status dan konten. Sebaiknya gunakan pustaka animasi ini jika memungkinkan untuk meningkatkan performa dan konsistensi untuk UWP UI.

Catatan Pustaka animasi tidak dapat menganimasikan semua properti yang mungkin. Untuk skenario XAML di mana pustaka animasi tidak berlaku, lihat Animasi storyboarded.

Menganimasikan properti CompositeTransform3D secara independen

Anda dapat menganimasikan setiap properti CompositeTransform3D secara independen, jadi hanya terapkan animasi yang Anda butuhkan. Untuk contoh dan info selengkapnya, lihat UIElement.Transform3D. Untuk informasi selengkapnya tentang menganimasikan transformasi, lihat Animasi storyboarded dan Animasi fungsi key-frame dan pelonggaran.

Mengoptimalkan sumber daya media

Audio, video, dan gambar adalah bentuk konten yang menarik yang digunakan sebagian besar aplikasi. Ketika tingkat penangkapan media meningkat dan konten berpindah dari definisi standar ke definisi tinggi, jumlah sumber daya yang perlu disimpan, didekodekan, dan memutar kembali konten ini meningkat. Kerangka kerja XAML dibangun pada fitur terbaru yang ditambahkan ke mesin media UWP sehingga aplikasi mendapatkan peningkatan ini secara gratis. Di sini kami menjelaskan beberapa trik tambahan yang memungkinkan Anda mendapatkan media maksimal di aplikasi UWP Anda.

Merilis aliran media

File media adalah beberapa aplikasi sumber daya yang paling umum dan mahal yang biasanya digunakan. Karena sumber daya file media dapat sangat meningkatkan ukuran jejak memori aplikasi, Anda harus ingat untuk merilis handel ke media segera setelah aplikasi selesai menggunakannya.

Misalnya, jika aplikasi Anda bekerja dengan RandomAccessStream atau objek IInputStream, pastikan untuk memanggil metode tutup pada objek saat aplikasi Anda selesai menggunakannya, untuk merilis objek yang mendasar.

Tampilkan pemutaran video layar penuh jika memungkinkan

Di aplikasi UWP, selalu gunakan properti IsFullWindow di MediaPlayerElement untuk mengaktifkan dan menonaktifkan penyajian jendela penuh. Ini memastikan pengoptimalan tingkat sistem digunakan selama pemutaran media.

Kerangka kerja XAML dapat mengoptimalkan tampilan konten video ketika itu adalah satu-satunya hal yang dirender, menghasilkan pengalaman yang menggunakan lebih sedikit daya dan menghasilkan kecepatan bingkai yang lebih tinggi. Untuk pemutaran media yang paling efisien, atur ukuran MediaPlayerElement menjadi lebar dan tinggi layar dan jangan tampilkan elemen XAML lainnya

Ada alasan yang sah untuk melapisi elemen XAML pada MediaPlayerElement yang mengambil lebar dan tinggi layar penuh, misalnya teks tertutup atau kontrol transportasi sesaat. Pastikan untuk menyembunyikan elemen-elemen ini (diatur Visibility="Collapsed") ketika tidak diperlukan untuk menempatkan pemutaran media kembali ke status yang paling efisien.

Menampilkan daya pennonaktifkanan dan konservasi

Untuk mencegah tampilan dinonaktifkan saat tindakan pengguna tidak lagi terdeteksi, seperti saat aplikasi memutar video, Anda dapat memanggil DisplayRequest.RequestActive.

Untuk menghemat daya dan masa pakai baterai, Anda harus memanggil DisplayRequest.RequestRelease untuk melepaskan permintaan tampilan segera setelah tidak lagi diperlukan.

Berikut adalah beberapa situasi ketika Anda harus merilis permintaan tampilan:

  • Pemutaran video dijeda, misalnya oleh tindakan pengguna, buffering, atau penyesuaian karena bandwidth terbatas.
  • Pemutaran berhenti. Misalnya, video selesai diputar atau presentasi selesai.
  • Terjadi kesalahan pemutaran. Misalnya, masalah konektivitas jaringan atau file yang rusak.

Letakkan elemen lain ke sisi video yang disematkan

Seringkali aplikasi menawarkan tampilan yang disematkan di mana video diputar dalam halaman. Sekarang Anda jelas kehilangan pengoptimalan layar penuh karena MediaPlayerElement bukan ukuran halaman dan ada objek XAML lain yang digambar. Waspadalah terhadap masuknya mode ini secara tidak sengaja dengan menggambar batas di sekitar MediaPlayerElement.

Jangan gambar elemen XAML di atas video saat dalam mode tersemat. Jika Anda melakukannya, kerangka kerja dipaksa untuk melakukan sedikit pekerjaan ekstra untuk menyusun adegan. Menempatkan kontrol transportasi di bawah elemen media yang disematkan alih-alih di atas video adalah contoh yang baik untuk mengoptimalkan situasi ini. Dalam gambar ini, bilah merah menunjukkan serangkaian kontrol transportasi (putar, jeda, hentikan, dll.).

MediaPlayerElement with overlaying elements

Jangan letakkan kontrol ini di atas media yang tidak layar penuh. Sebagai gantinya, letakkan kontrol transportasi di suatu tempat di luar area tempat media dirender. Pada gambar berikutnya, kontrol ditempatkan di bawah media.

MediaPlayerElement with neighboring elements

Penundaan pengaturan sumber untuk MediaPlayerElement

Mesin media adalah objek mahal dan kerangka kerja XAML menunda pemuatan dll dan membuat objek besar selama mungkin. MediaPlayerElement dipaksa untuk melakukan pekerjaan ini setelah sumbernya diatur melalui properti Sumber. Mengatur ini ketika pengguna benar-benar siap untuk memutar media menunda sebagian besar biaya yang terkait dengan MediaPlayerElement selama mungkin.

Mengatur MediaPlayerElement.PosterSource

Mengatur MediaPlayerElement.PosterSource memungkinkan XAML merilis beberapa sumber daya GPU yang jika tidak digunakan. API ini memungkinkan aplikasi untuk menggunakan memori sesedikitan mungkin.

Meningkatkan scrubbing media

Scrubbing selalu merupakan tugas yang berat bagi platform media untuk membuat responsif. Umumnya orang menyelesaikan ini dengan mengubah nilai Slider. Berikut adalah beberapa tips tentang cara membuat ini seefisien mungkin:

Cocokkan resolusi video dengan resolusi perangkat

Video decoding membutuhkan banyak siklus memori dan GPU, jadi pilih format video yang dekat dengan resolusi yang akan ditampilkan. Tidak ada gunanya menggunakan sumber daya untuk mendekode video 1080 jika akan diturunkan skalanya ke ukuran yang jauh lebih kecil. Banyak aplikasi tidak memiliki video yang sama yang dikodekan pada resolusi yang berbeda; tetapi jika tersedia, gunakan pengodean yang dekat dengan resolusi tempat pengodean akan ditampilkan.

Pemilihan format media dapat menjadi topik sensitif dan sering didorong oleh keputusan bisnis. Dari perspektif performa UWP, kami merekomendasikan video H.264 sebagai format video utama dan AAC dan MP3 sebagai format audio pilihan. Untuk pemutaran file lokal, MP4 adalah kontainer file pilihan untuk konten video. Decoding H.264 dipercepat melalui perangkat keras grafis terbaru. Selain itu, meskipun akselerasi perangkat keras untuk dekode VC-1 tersedia secara luas, untuk sekumpulan besar perangkat keras grafis di pasar, akselerasi terbatas dalam banyak kasus ke tingkat akselerasi parsial (atau tingkat IDCT), daripada offload perangkat keras tingkat uap penuh (yaitu mode VLD).

Jika Anda memiliki kontrol penuh atas proses pembuatan konten video, Anda harus mencari tahu cara menjaga keseimbangan yang baik antara efisiensi kompresi dan struktur GOP. Ukuran GOP yang relatif lebih kecil dengan gambar B dapat meningkatkan performa dalam mode pencarian atau trik.

Ketika menyertakan efek audio latensi rendah yang pendek, misalnya dalam game, gunakan file WAV dengan data PCM yang tidak dikompresi untuk mengurangi overhead pemrosesan yang khas untuk format audio terkompresi.

Mengoptimalkan sumber daya gambar

Menskalakan gambar ke ukuran yang sesuai

Gambar diambil pada resolusi yang sangat tinggi, yang dapat menyebabkan aplikasi menggunakan lebih banyak CPU saat mendekode data gambar dan lebih banyak memori setelah dimuat dari disk. Tetapi tidak ada gunanya mendekode dan menyimpan gambar resolusi tinggi dalam memori hanya untuk menampilkannya lebih kecil dari ukuran aslinya. Sebagai gantinya, buat versi gambar pada ukuran yang tepat akan digambar di layar menggunakan properti DecodePixelWidth dan DecodePixelHeight.

Jangan lakukan ini:

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

Sebagai gantinya, lakukan ini:

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

Unit untuk DecodePixelWidth dan DecodePixelHeight adalah piksel fisik default. Properti DecodePixelType dapat digunakan untuk mengubah perilaku ini: mengatur DecodePixelType ke Hasil logis dalam ukuran dekode secara otomatis memperhitungkan faktor skala sistem saat ini, mirip dengan konten XAML lainnya. Oleh karena itu, umumnya akan sesuai untuk mengatur DecodePixelType ke Logical jika, misalnya, Anda ingin DecodePixelWidth dan DecodePixelHeight cocok dengan properti Tinggi dan Lebar dari kontrol Gambar tempat gambar akan ditampilkan. Dengan perilaku default menggunakan piksel fisik, Anda harus memperhitungkan sendiri faktor skala sistem saat ini; dan Anda harus mendengarkan pemberitahuan perubahan skala jika pengguna mengubah preferensi tampilan mereka.

Jika DecodePixelWidth/Height secara eksplisit diatur lebih besar dari gambar akan ditampilkan di layar, aplikasi tidak perlu menggunakan memori tambahan—hingga 4 byte per piksel—yang dengan cepat menjadi mahal untuk gambar besar. Gambar juga akan diskalakan ke bawah menggunakan penskalaan bilinear yang dapat menyebabkannya tampak buram untuk faktor skala besar.

Jika DecodePixelWidth/DecodePixelHeight secara eksplisit diatur lebih kecil dari gambar akan ditampilkan di layar maka akan ditingkatkan skalanya dan dapat muncul tanpa piksel.

Dalam beberapa kasus di mana ukuran dekode yang sesuai tidak dapat ditentukan sebelumnya, Anda harus menunda decoding ukuran kanan otomatis XAML yang akan melakukan upaya terbaik untuk mendekode gambar pada ukuran yang sesuai jika DecodePixelWidth/DecodePixelHeight eksplisit tidak ditentukan.

Anda harus mengatur ukuran dekode eksplisit jika Anda mengetahui ukuran konten gambar sebelumnya. Anda juga harus secara bersamaan mengatur DecodePixelType ke Logical jika ukuran dekode yang disediakan relatif terhadap ukuran elemen XAML lainnya. Misalnya, jika Anda secara eksplisit mengatur ukuran konten dengan Image.Width dan Image.Height, Anda dapat mengatur DecodePixelType ke DecodePixelType.Logical untuk menggunakan dimensi piksel logis yang sama sebagai kontrol Gambar dan kemudian secara eksplisit menggunakan BitmapImage.DecodePixelWidth dan/atau BitmapImage.DecodePixelHeight untuk mengontrol ukuran gambar untuk mencapai penghematan memori yang berpotensi besar.

Perhatikan bahwa Image.Stretch harus dipertimbangkan saat menentukan ukuran konten yang didekodekan.

Decoding berukuran kanan

Jika Anda tidak mengatur ukuran dekode eksplisit, XAML akan melakukan upaya terbaik untuk menyimpan memori dengan mendekode gambar ke ukuran yang tepat yang akan muncul di layar sesuai dengan tata letak awal halaman yang berisi. Anda disarankan untuk menulis aplikasi sedih untuk menggunakan fitur ini jika memungkinkan. Fitur ini akan dinonaktifkan jika salah satu kondisi berikut terpenuhi.

Dalam skenario di atas, mengatur ukuran dekode eksplisit adalah satu-satunya cara untuk mencapai penghematan memori.

Anda harus selalu melampirkan BitmapImage ke pohon langsung sebelum mengatur sumber. Setiap kali elemen gambar atau kuas ditentukan dalam markup, ini akan secara otomatis terjadi. Contoh disediakan di bawah judul "Contoh pohon langsung". Anda harus selalu menghindari penggunaan SetSource dan sebagai gantinya menggunakan SetSourceAsync saat mengatur sumber aliran. Dan ada baiknya untuk menghindari menyembunyikan konten gambar (baik dengan opasitas nol atau dengan visibilitas yang diciutkan) sambil menunggu peristiwa ImageOpened dinaikkan. Melakukan ini adalah panggilan penilaian: Anda tidak akan mendapat manfaat dari decoding berukuran kanan otomatis jika dilakukan. Jika aplikasi Anda harus menyembunyikan konten gambar pada awalnya, aplikasi juga harus mengatur ukuran dekode secara eksplisit jika memungkinkan.

Contoh pohon langsung

Contoh 1 (baik)—Pengidentifikasi Sumber Daya Seragam (URI) yang ditentukan dalam markup.

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

Contoh 2 markup—URI yang ditentukan dalam code-behind.

<Image x:Name="myImage"/>

Contoh 2 code-behind (baik)—menyambungkan BitmapImage ke pohon sebelum mengatur UriSource-nya.

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

Contoh 2 code-behind (buruk)—mengatur UriSource BitmapImage sebelum menyambungkannya ke pohon.

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

Pengoptimalan penembolokan

Pengoptimalan penembolokan berlaku untuk gambar yang menggunakan UriSource untuk memuat konten dari paket aplikasi atau dari web. URI digunakan untuk mengidentifikasi konten yang mendasar secara unik, dan secara internal kerangka kerja XAML tidak akan mengunduh atau mendekode konten beberapa kali. Sebagai gantinya, ia akan menggunakan sumber daya perangkat lunak atau perangkat keras yang di-cache untuk menampilkan konten beberapa kali.

Pengecualian untuk pengoptimalan ini adalah jika gambar ditampilkan beberapa kali pada resolusi yang berbeda (yang dapat ditentukan secara eksplisit atau melalui decoding berukuran kanan otomatis). Setiap entri cache juga menyimpan resolusi gambar, dan jika XAML tidak dapat menemukan gambar dengan URI sumber yang cocok dengan resolusi yang diperlukan maka akan mendekode versi baru pada ukuran tersebut. Namun, ini tidak akan mengunduh data gambar yang dikodekan lagi.

Akibatnya, Anda harus merangkul menggunakan UriSource saat memuat gambar dari paket aplikasi, dan menghindari penggunaan aliran file dan SetSourceAsync saat tidak diperlukan.

Gambar di panel virtual (ListView, misalnya)

Jika gambar dihapus dari pohon—karena aplikasi secara eksplisit menghapusnya, atau karena berada di panel virtual modern dan secara implisit dihapus saat digulir keluar dari tampilan—maka XAML akan mengoptimalkan penggunaan memori dengan merilis sumber daya perangkat keras untuk gambar karena tidak lagi diperlukan. Memori tidak segera dirilis, melainkan dirilis selama pembaruan bingkai yang terjadi setelah satu detik elemen gambar tidak lagi berada di pohon.

Akibatnya, Anda harus berusaha untuk menggunakan panel virtual modern untuk menghosting daftar konten gambar.

Gambar yang dirasterisasi perangkat lunak

Ketika gambar digunakan untuk sikat non-persegi panjang atau untuk NineGrid, gambar akan menggunakan jalur rasterisasi perangkat lunak, yang tidak akan menskalakan gambar sama sekali. Selain itu, ia harus menyimpan salinan gambar di memori perangkat lunak dan perangkat keras. Misalnya, jika gambar digunakan sebagai kuas untuk elips, gambar penuh yang berpotensi besar akan disimpan dua kali secara internal. Saat menggunakan NineGrid atau kuas non-persegi panjang, aplikasi Anda harus melakukan pra-skala gambarnya ke ukuran yang akan dirender.

Pemuatan gambar utas latar belakang

XAML memiliki pengoptimalan internal yang memungkinkannya untuk mendekode konten gambar secara asinkron ke permukaan dalam memori perangkat keras tanpa memerlukan permukaan menengah dalam memori perangkat lunak. Ini mengurangi penggunaan memori puncak dan latensi penyajian. Fitur ini akan dinonaktifkan jika salah satu kondisi berikut terpenuhi.

  • Gambar digunakan sebagai NineGrid.
  • CacheMode="BitmapCache" diatur pada elemen gambar atau pada elemen induk apa pun.
  • Kuas gambar tidak persegi panjang (seperti saat diterapkan ke bentuk atau ke teks).

SoftwareBitmapSource

Kelas SoftwareBitmapSource bertukar gambar yang tidak dikompresi yang dapat dioperasikan antara namespace WinRT yang berbeda seperti BitmapDecoder, API kamera, dan XAML. Kelas ini merintangi salinan tambahan yang biasanya diperlukan dengan WriteableBitmap, dan yang membantu mengurangi memori puncak dan latensi sumber ke layar.

SoftwareBitmap yang menyediakan informasi sumber juga dapat dikonfigurasi untuk menggunakan IWICBitmap kustom untuk menyediakan penyimpanan backing yang dapat dimuat ulang yang memungkinkan aplikasi memetakan ulang memori sesuai keinginan. Ini adalah kasus penggunaan C++ tingkat lanjut.

Aplikasi Anda harus menggunakan SoftwareBitmap dan SoftwareBitmapSource untuk beroperasi dengan API WinRT lainnya yang menghasilkan dan menggunakan gambar. Dan aplikasi Anda harus menggunakan SoftwareBitmapSource saat memuat data gambar yang tidak dikompresi alih-alih menggunakan WriteableBitmap.

Menggunakan GetThumbnailAsync untuk gambar mini

Satu kasus penggunaan untuk menskalakan gambar adalah membuat gambar mini. Meskipun Anda dapat menggunakan DecodePixelWidth dan DecodePixelHeight untuk menyediakan versi gambar yang kecil, UWP menyediakan API yang lebih efisien untuk mengambil gambar mini. GetThumbnailAsync menyediakan gambar mini untuk gambar yang memiliki sistem file yang sudah di-cache. Ini memberikan performa yang lebih baik daripada API XAML karena gambar tidak perlu dibuka atau didekodekan.

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

Dekode gambar sekali

Untuk mencegah gambar didekode lebih dari sekali, tetapkan properti Image.Source dari Uri daripada menggunakan aliran memori. Kerangka kerja XAML dapat mengaitkan Uri yang sama di beberapa tempat dengan satu gambar yang didekodekan, tetapi tidak dapat melakukan hal yang sama untuk beberapa aliran memori yang berisi data yang sama dan membuat gambar yang didekodekan yang berbeda untuk setiap aliran memori.