Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Windows.Graphics.Capture namespace menyediakan API untuk mengambil frame dari tampilan atau jendela aplikasi, guna membuat aliran video atau cuplikan untuk membangun pengalaman kolaboratif dan interaktif.
Dengan tangkapan layar, pengembang memanggil UI sistem aman bagi pengguna akhir untuk memilih tampilan atau jendela aplikasi yang akan diambil, dan batas pemberitahuan kuning digambar oleh sistem di sekitar item yang diambil secara aktif. Dalam kasus beberapa sesi pengambilan simultan, batas kuning digambar di sekitar setiap item yang diambil.
Note
API pengambilan layar hanya didukung pada perangkat desktop Windows dan Windows Mixed Reality headset imersif.
Artikel ini menjelaskan menangkap satu gambar jendela tampilan atau aplikasi.
Periksa dukungan tangkapan layar
Sebelum mencoba mengambil, periksa apakah perangkat saat ini mendukung tangkapan layar. Gunakan metode IsSupported pada GraphicsCaptureSession untuk menentukan apakah tangkapan layar tersedia:
// Check if screen capture is supported
if (!GraphicsCaptureSession.IsSupported())
{
// Hide capture UI
CaptureControlsPanel.Visibility = Visibility.Collapsed;
PreviewPlaceholderText.Text = "Screen capture isn't supported on this device.";
UpdateStatus("Screen capture isn't supported on this device.");
return;
}
Ada beberapa alasan mengapa tangkapan layar mungkin tidak didukung, termasuk jika perangkat tidak memenuhi persyaratan perangkat keras.
Luncurkan antarmuka pengguna sistem untuk memulai pengambilan layar
Gunakan kelas GraphicsCapturePicker untuk memanggil UI pemilih sistem. Pengguna akhir menggunakan UI ini untuk memilih jendela tampilan atau aplikasi yang akan diambil. Pemilih mengembalikan GraphicsCaptureItem yang digunakan untuk membuat sesi pengambilan.
Dalam aplikasi WinUI 3, Anda harus menginisialisasi pemilih dengan handel jendela sebelum memanggil PickSingleItemAsync:
// Launch picker and start capture
var picker = new GraphicsCapturePicker();
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
GraphicsCaptureItem item = await picker.PickSingleItemAsync();
if (item != null)
{
StartCaptureInternal(item);
}
Buat kumpulan frame tangkapan dan sesi tangkapan
Menggunakan GraphicsCaptureItem, buat Direct3D11CaptureFramePool dengan perangkat D3D Anda, format piksel yang didukung (DXGI_FORMAT_B8G8R8A8_UNORM), jumlah bingkai yang diinginkan (yang dapat berupa bilangan bulat apa pun), dan ukuran bingkai. Properti Ukuran kelas GraphicsCaptureItem dapat digunakan sebagai ukuran bingkai Anda:
// Create frame pool and capture session
_framePool = Direct3D11CaptureFramePool.Create(
_canvasDevice,
CaptureDirectXPixelFormat.B8G8R8A8UIntNormalized,
BufferCount,
item.Size);
_session = _framePool.CreateCaptureSession(item);
Note
Pada sistem dengan Windows HD Color diaktifkan, format piksel konten mungkin tidak selalu DXGI_FORMAT_B8G8R8A8_UNORM. Untuk menghindari kliping piksel berlebihan (yaitu konten yang ditangkap tampak pudar) saat menangkap konten HDR, pertimbangkan untuk menggunakan DXGI_FORMAT_R16G16B16A16_FLOAT untuk setiap komponen dalam alur penangkapan, termasuk Direct3D11CaptureFramePool dan tujuan akhir seperti CanvasBitmap. Tergantung pada kebutuhan, pemrosesan tambahan seperti menyimpan ke format konten HDR atau pemetaan nada HDR-ke-SDR mungkin diperlukan. Artikel ini berfokus pada pengambilan konten SDR. Untuk informasi selengkapnya, lihat Menggunakan DirectX dengan tampilan rentang dinamis tinggi dan warna tingkat lanjut.
Setelah pengguna secara eksplisit memberikan persetujuan untuk menangkap jendela aplikasi atau tampilan di antarmuka pengguna sistem, GraphicsCaptureItem dapat dikaitkan dengan beberapa sesi pengambilan. Dengan cara ini aplikasi Anda dapat memilih untuk mengambil item yang sama untuk berbagai pengalaman.
Memperoleh bingkai pengambilan
Dengan kumpulan bingkai dan sesi pengambilan Anda dibuat, panggil StartCapture pada instans GraphicsCaptureSession Anda untuk memberi tahu sistem untuk mulai mengirim bingkai pengambilan ke aplikasi Anda.
Untuk memperoleh bingkai pengambilan ini, yang merupakan objek Direct3D11CaptureFrame , gunakan peristiwa Direct3D11CaptureFramePool.FrameArrived :
// Handle frame arrival
_framePool.FrameArrived += OnFrameArrived;
Disarankan untuk menghindari melakukan tugas berat pada utas UI saat menangani FrameArrived, karena event ini dipicu setiap kali frame baru tersedia. Jika Anda memilih untuk mendengarkan FrameArrived di utas UI, perhatikan berapa banyak pekerjaan yang Anda lakukan setiap kali peristiwa diaktifkan.
Atau, Anda dapat menarik bingkai secara manual dengan metode Direct3D11CaptureFramePool.TryGetNextFrame hingga Anda mendapatkan semua bingkai yang Anda butuhkan.
Objek Direct3D11CaptureFrame berisi properti ContentSize, Surface, dan SystemRelativeTime. SystemRelativeTime adalah waktu QPC (QueryPerformanceCounter) yang dapat digunakan untuk menyinkronkan elemen media lainnya.
Bingkai pengambilan proses
Setiap bingkai dari Direct3D11CaptureFramePool dicek keluar saat memanggil TryGetNextFrame, dan diperiksa kembali sesuai dengan masa pakai objek Direct3D11CaptureFrame . Untuk aplikasi terkelola, disarankan untuk menggunakan metode Direct3D11CaptureFrame.Dispose . Direct3D11CaptureFrame mengimplementasikan IDisposable, sehingga membuang bingkai mengembalikan buffer ke kumpulan.
Aplikasi tidak boleh menyimpan referensi ke objek Direct3D11CaptureFrame , juga tidak boleh menyimpan referensi ke permukaan Direct3D yang mendasarinya setelah bingkai diperiksa kembali.
Dalam contoh ini, setiap bingkai dikonversi ke CanvasBitmap, yang merupakan bagian dari pustaka Win2D :
// Convert frame to Win2D bitmap and display
CanvasBitmap canvasBitmap = CanvasBitmap.CreateFromDirect3D11Surface(
_canvasDevice,
frame.Surface);
Permukaan Direct3D yang mendasarinya selalu berukuran sesuai dengan yang ditentukan saat Direct3D11CaptureFramePool dibuat (atau dibuat ulang). Jika konten lebih besar dari bingkai, isinya akan dipotong sesuai ukuran bingkai. Jika konten lebih kecil dari bingkai, bingkai lainnya berisi data yang tidak ditentukan. Disarankan agar aplikasi menyalin sub-rect menggunakan properti ContentSize untuk Direct3D11CaptureFrame tersebut untuk menghindari menampilkan konten yang tidak ditentukan.
Menyimpan cuplikan layar
Setelah Anda memiliki CanvasBitmap, Anda dapat menyimpannya sebagai file gambar. Contoh berikut menyimpan bingkai saat ini sebagai file PNG menggunakan FileSavePicker. Pada aplikasi WinUI 3, Anda harus menginisialisasi picker dengan handle jendela:
// Save screenshot
var savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.SuggestedFileName = "screen-capture";
savePicker.FileTypeChoices.Add("PNG image", new List<string> { ".png" });
WinRT.Interop.InitializeWithWindow.Initialize(savePicker, _hwnd);
StorageFile? file = await savePicker.PickSaveFileAsync();
if (file is not null)
{
using var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite);
await frameToSave.SaveAsync(fileStream, CanvasBitmapFileFormat.Png, 1f);
}
Bereaksi terhadap mengubah ukuran item atau perangkat yang hilang
Selama proses pengambilan, aplikasi mungkin ingin mengubah aspek Direct3D11CaptureFramePool mereka. Ini termasuk menyediakan perangkat Direct3D baru, mengubah ukuran buffer bingkai, atau bahkan mengubah jumlah buffer dalam kumpulan. Dalam setiap skenario ini, metode Buat ulang pada objek Direct3D11CaptureFramePool adalah pendekatan yang direkomendasikan.
Ketika Dibuat ulang dipanggil, semua bingkai yang ada akan dibuang. Ini untuk mencegah membagikan bingkai yang permukaan Direct3D yang mendasarnya milik perangkat yang mungkin tidak lagi dapat diakses oleh aplikasi. Karena itu, sebaiknya proses semua frame yang tertunda sebelum memanggil Recreate.
Pertimbangan WinUI 3
Saat memigrasikan kode pengambilan layar dari UWP ke WinUI 3 (SDK Aplikasi Windows), ingatlah perbedaan berikut:
- Inisialisasi handle jendela — Picker seperti GraphicsCapturePicker dan FileSavePicker harus diinisialisasi dengan handle jendela menggunakan InitializeWithWindow. Untuk informasi selengkapnya, lihat Mendapatkan handle jendela (HWND).
- API Komposisi pada utas UI — Di WinUI 3, operasi permukaan CanvasComposition (seperti menggambar ke CompositionDrawingSurface) harus dikirim ke utas UI menggunakan DispatcherQueue.TryEnqueue. Pengambilan bingkai dan pembuatan bitmap dapat dilakukan pada utas latar belakang kumpulan bingkai, tetapi pembaruan visual komposisi harus dilakukan pada utas UI.
-
Perubahan namespace — Gunakan
Microsoft.UI.Composition,Microsoft.UI.Xaml.Hosting, danMicrosoft.UI.Dispatchingalih-alih versiWindows.UI. NamespaceWindows.Graphics.Capturetetap tidak berubah.
Baca juga
- namespace Windows.Graphics.Capture
- Win2D untuk WinUI 3
- Mengambil sebuah handle jendela (HWND)
- Grafik — Indeks fitur pengembangan grafis untuk aplikasi Windows
- Sampel Grafik DirectX pada GitHub
Windows developer