Laden eines Bilds in Direct2D-Effekte mit dem FilePicker
Zeigt, wie Sie windows ::Storage::P ickers::FileOpenPicker verwenden, um ein Bild in Direct2D-Effekte zu laden. Wenn Sie dem Benutzer erlauben möchten, eine Bilddatei aus dem Speicher in einer Windows Store-App auszuwählen, wird empfohlen, fileOpenPicker zu verwenden.
Wichtige Informationen
Technologien
Voraussetzungen
- Sie benötigen ein ID2D1DeviceContext-Objekt zum Erstellen von Effekten.
- Zum Erstellen von WIC-Objekten benötigen Sie ein IWICImagingFactory-Objekt .
Anweisungen
Schritt 1: Öffnen der Dateiauswahl
Erstellen Sie ein FileOpenPicker-Objekt , und legen Sie viewMode, SuggestedStartLocation und FileTypeFilter zum Auswählen von Bildern fest. Rufen Sie die PickSingleFileAsync-Methode auf.
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
openPicker->FileTypeFilter->Append(".jpg");
auto pickOperation = openPicker->PickSingleFileAsync();
Nach Abschluss von PickSingleFileAsync erhalten Sie einen Dateidatenstrom von der IAsyncOperation-Schnittstelle , die zurückgegeben wird.
Schritt 2: Abrufen eines Dateidatenstroms
Deklarieren Sie einen Vervollständigungshandler, der ausgeführt werden soll, nachdem der asynchrone Vorgang der Dateiauswahl zurückgegeben wurde. Verwenden Sie die GetResults-Methode , um die Datei und das Dateistreamobjekt abzurufen.
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);
});
}
});
Im nächsten Schritt konvertieren Sie das IRandomAccessStream-Objekt in einen IStream , den Sie an WIC übergeben können.
Schritt 3: Konvertieren des Dateidatenstroms
Verwenden Sie die CreateStreamOverRandomAccessStream-Funktion , um den Dateidatenstrom zu konvertieren. Windows-Runtime-APIs stellen Streams mit IRandomAccessStream dar, während WICIStream nutzt.
ComPtr<IStream> istream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
reinterpret_cast<IUnknown*>(fileStream),
IID_PPV_ARGS(&istream)
)
);
Hinweis
Um die CreateStreamOverRandomAccessStream-Funktion zu verwenden, sollten Sie shcore.h in Ihr Projekt einschließen.
Schritt 4: Erstellen eines WIC-Decoders und Abrufen des Frames
Erstellen Sie mithilfe der IWICImagingFactory::CreateDecoderFromStream-Methode ein IWICBitmapDecoder-Objekt.
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(
m_wicFactory->CreateDecoderFromStream(
istream.Get(),
nullptr,
WICDecodeMetadataCacheOnDemand,
&decoder
)
);
Rufen Sie den ersten Frame des Bilds mithilfe der IWICBitmapDecoder::GetFrame-Methode vom Decoder ab.
ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(
decoder->GetFrame(0, &frame)
);
Schritt 5: Erstellen eines WIC-Konverters und Initialisieren
Konvertieren Sie das Bild mithilfe von WIC in das BGRA-Farbformat. IWICBitmapFrameDecode gibt das native Pixelformat des Bilds zurück, wie JPEGs in GUID_WICPixelFormat24bppBGR gespeichert werden. Als Leistungsoptimierung mit Direct2D wird jedoch empfohlen, dass Sie in WICPixelFormat32bppPBGRA konvertieren.
Erstellen Sie mithilfe der IWICImagingFactory::CreateFormatConverter-Methode ein IWICFormatConverter-Objekt.
ComPtr<IWICFormatConverter> converter; DX::ThrowIfFailed( m_wicFactory->CreateFormatConverter(&converter) );
Initialisieren Sie den Formatkonverter, um wiCPixelFormat32bppPBGRA zu verwenden und den Bitmapframe zu übergeben.
DX::ThrowIfFailed( converter->Initialize( frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom // premultiplied BGRA has no paletting, so this is ignored ) );
Die IWICFormatConverter-Schnittstelle wird von der IWICBitmapSource-Schnittstelle abgeleitet, sodass Sie den Konverter an den Bitmapquelleffekt übergeben können.
Schritt 6: Erstellen eines Effekts und Übergeben einer IWICBitmapSource
Verwenden Sie die CreateEffect-Methode, um ein Bitmapquelle-ID2D1Effect-Objekt mithilfe des Direct2D-Gerätekontexts zu erstellen.
Verwenden Sie die ID2D1Effect::SetValue-Methode, um die eigenschaft D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE auf den WIC-Formatkonverter festzulegen.
Hinweis
Der Bitmap-Quelleffekt nimmt keine Eingabe aus der SetInput-Methode wie viele Direct2D-Effekte an. Stattdessen wird das IWICBitmapSource-Objekt als -Eigenschaft angegeben.
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.
Nachdem Sie nun über den Bitmapquelleneffekt verfügen, können Sie ihn als Eingabe für jeden ID2D1Effect verwenden und ein Effektdiagramm erstellen.
Vollständiges Beispiel
Hier ist der vollständige Code für dieses Beispiel.
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.
}
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für