Comment charger une image dans des effets Direct2D à l’aide de FilePicker
Montre comment utiliser Windows::Storage::P ickers::FileOpenPicker pour charger une image dans des effets Direct2D. Si vous souhaitez permettre à l’utilisateur de sélectionner un fichier image à partir d’un stockage dans une application du Windows Store, nous vous recommandons d’utiliser FileOpenPicker.
Bon à savoir
Technologies
Prérequis
- Vous avez besoin d’un objet ID2D1DeviceContext pour créer des effets.
- Vous avez besoin d’un objet IWICImagingFactory pour créer des objets WIC.
Instructions
Étape 1 : Ouvrir le sélecteur de fichiers
Créez un objet FileOpenPicker et définissez le ViewMode, SuggestedStartLocation et le FileTypeFilter pour sélectionner des images. Appelez la méthode PickSingleFileAsync .
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
openPicker->FileTypeFilter->Append(".jpg");
auto pickOperation = openPicker->PickSingleFileAsync();
Une fois pickSingleFileAsync terminé, vous obtenez un flux de fichiers à partir de l’interface IAsyncOperation qu’il retourne.
Étape 2 : Obtenir un flux de fichiers
Déclarez un gestionnaire d’achèvement à exécuter après le retour de l’opération asynchrone du sélecteur de fichiers. Utilisez la méthode GetResults pour récupérer le fichier et obtenir l’objet de flux de fichiers.
pickOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(
[=](IAsyncOperation<StorageFile^> ^operation, AsyncStatus status)
{
auto file = operation->GetResults();
if (file) // If file == nullptr, the user did not select a file.
{
auto openOperation = file->OpenAsync(FileAccessMode::Read);
openOperation->Completed = ref new
AsyncOperationCompletedHandler<IRandomAccessStream^>(
[=](IAsyncOperation<IRandomAccessStream^> ^operation, AsyncStatus status)
{
auto fileStream = operation->GetResults();
// Pass IRandomAccessStream^ into DirectXApp for decoding/processing.
OpenFile(fileStream);
});
}
});
À l’étape suivante, vous convertissez l’objet IRandomAccessStream en un IStream que vous pouvez passer à WIC.
Étape 3 : Convertir le flux de fichiers
Utilisez la fonction CreateStreamOverRandomAccessStream pour convertir le flux de fichiers. Windows Runtime API représentent des flux avec IRandomAccessStream, tandis que WIC consomme IStream.
ComPtr<IStream> istream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
reinterpret_cast<IUnknown*>(fileStream),
IID_PPV_ARGS(&istream)
)
);
Notes
Pour utiliser la fonction CreateStreamOverRandomAccessStream , vous devez inclure shcore.h dans votre projet.
Étape 4 : Créer un décodeur WIC et obtenir le cadre
Créez un objet IWICBitmapDecoder à l’aide de la méthode IWICImagingFactory::CreateDecoderFromStream .
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(
m_wicFactory->CreateDecoderFromStream(
istream.Get(),
nullptr,
WICDecodeMetadataCacheOnDemand,
&decoder
)
);
Obtenez la première image de l’image à partir du décodeur à l’aide de la méthode IWICBitmapDecoder::GetFrame .
ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(
decoder->GetFrame(0, &frame)
);
Étape 5 : Créer un convertisseur WIC et initialiser
Convertissez l’image au format de couleur BGRA à l’aide de WIC. IWICBitmapFrameDecode retourne le format de pixel natif de l’image, comme les fichiers JPEG sont stockés dans GUID_WICPixelFormat24bppBGR. Toutefois, en tant qu’optimisation des performances avec Direct2D, nous vous recommandons de convertir en WICPixelFormat32bppPBGRA.
Créez un objet IWICFormatConverter à l’aide de la méthode IWICImagingFactory::CreateFormatConverter .
ComPtr<IWICFormatConverter> converter; DX::ThrowIfFailed( m_wicFactory->CreateFormatConverter(&converter) );
Initialisez le convertisseur de format pour utiliser le WICPixelFormat32bppPBGRA et passez le cadre bitmap.
DX::ThrowIfFailed( converter->Initialize( frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom // premultiplied BGRA has no paletting, so this is ignored ) );
L’interface IWICFormatConverter est dérivée de l’interface IWICBitmapSource. Vous pouvez donc passer le convertisseur à l’effet source bitmap.
Étape 6 : Créer un effet et passer un IWICBitmapSource
Utilisez la méthode CreateEffect pour créer un objet ID2D1Effectsource bitmap à l’aide du contexte d’appareilDirect2D.
Utilisez la méthode ID2D1Effect::SetValue pour définir la propriété D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE sur le convertisseur de formatWIC.
Notes
L’effet source bitmap ne prend pas d’entrée de la méthode SetInput comme de nombreux effets Direct2D. Au lieu de cela, l’objet IWICBitmapSource est spécifié en tant que propriété.
ComPtr<ID2D1Effect> bitmapSourceEffect;
DX::ThrowIfFailed(
m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect)
);
DX::ThrowIfFailed(
bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, converter.Get())
);
// Insert code using the bitmap source in an effect graph.
Maintenant que vous avez l’effet source bitmap , vous pouvez l’utiliser comme entrée dans n’importe quel ID2D1Effect et créer un graphe d’effets.
Exemple complet
Voici le code complet de cet exemple.
ComPtr<ID2D1Effect> bitmapSourceEffect;
void OpenFilePicker()
{
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
openPicker->FileTypeFilter->Append(".jpg");
auto pickOperation = openPicker->PickSingleFileAsync();
pickOperation->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(
[=](IAsyncOperation<StorageFile^> ^operation, AsyncStatus status)
{
auto file = operation->GetResults();
if (file)
{
auto openOperation = file->OpenAsync(FileAccessMode::Read);
openOperation->Completed = ref new
AsyncOperationCompletedHandler<IRandomAccessStream^>(
[=](IAsyncOperation<IRandomAccessStream^> ^operation, AsyncStatus status)
{
auto fileStream = operation->GetResults();
// Pass IRandomAccessStream^ into DirectXApp for decoding/processing.
OpenFile(fileStream);
});
}
});
}
void OpenFile(Windows::Storage::Streams::IRandomAccessStream^ fileStream)
{
ComPtr<IStream> istream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
reinterpret_cast<IUnknown*>(fileStream),
IID_PPV_ARGS(&istream)
)
);
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(
m_wicFactory->CreateDecoderFromStream(
istream.Get(),
nullptr,
WICDecodeMetadataCacheOnDemand,
&decoder
)
);
ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(
decoder->GetFrame(0, &frame)
);
ComPtr<IWICFormatConverter> converter;
DX::ThrowIfFailed(
m_wicFactory->CreateFormatConverter(&converter)
);
DX::ThrowIfFailed(
converter->Initialize(
frame.Get(),
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.0f,
WICBitmapPaletteTypeCustom // premultiplied BGRA has no paletting, so this is ignored
)
);
ComPtr<ID2D1Effect> bitmapSourceEffect;
DX::ThrowIfFailed(
m_d2dContext->CreateEffect(CLSID_D2D1BitmapSource, &bitmapSourceEffect)
);
DX::ThrowIfFailed(
bitmapSourceEffect->SetValue(D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE, converter.Get())
);
// Insert code using the bitmap source in an effect graph.
}
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour