Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Zeigt, wie Sie Windows::Storage::Pickers::FileOpenPicker verwenden, um ein Bild in Direct2D-Effekte zu laden. Wenn Sie den Benutzer*innen in einer Windows Store-App die Möglichkeit geben möchten, eine gespeicherte Bilddatei auszuwählen, empfehlen wir Ihnen, den FileOpenPicker zu verwenden.
Wichtige Informationen
Technologie
Voraussetzungen
- Sie benötigen ein ID2D1DeviceContext-Objekt, um Effekte zu erstellen.
- Sie benötigen ein IWICImagingFactory-Objekt, um WIC-Objekte zu erstellen.
Anweisungen
Schritt 1: Öffnen Sie den File-Picker
Erstellen Sie ein FileOpenPicker-Objekt, und legen Sie den ViewMode, SuggestedStartLocation und den FileTypeFilter für die Auswahl von Bildern fest. Rufen Sie die Methode PickSingleFileAsync auf.
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
openPicker->FileTypeFilter->Append(".jpg");
auto pickOperation = openPicker->PickSingleFileAsync();
Nachdem PickSingleFileAsync abgeschlossen ist, erhalten Sie einen File-Stream von der IAsyncOperation-Schnittstelle.
Schritt 2: Abrufen eines File-Streams
Deklarieren Sie einen Handler, der nach der Rückkehr des asynchronen Vorgangs des File-Pickers ausgeführt wird. Verwenden Sie die Methode GetResults, um die Datei abzurufen und das File-Stream-Objekt zu erhalten.
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 Sie den File-Stream
Verwenden Sie die Funktion CreateStreamOverRandomAccessStream, um den File-Stream zu konvertieren. Windows Runtime-APIs repräsentieren Streams über IRandomAccessStream, während WIC IStream verwendet.
ComPtr<IStream> istream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
reinterpret_cast<IUnknown*>(fileStream),
IID_PPV_ARGS(&istream)
)
);
Hinweis
Um die Funktion CreateStreamOverRandomAccessStream zu verwenden, sollten Sie shcore.h in Ihr Projekt aufnehmen.
Schritt 4: Erstellen Sie einen WIC-Decoder, und holen Sie sich den Frame
Erstellen Sie ein IWICBitmapDecoder-Objekt mit der IWICImagingFactory::CreateDecoderFromStream-Methode.
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(
m_wicFactory->CreateDecoderFromStream(
istream.Get(),
nullptr,
WICDecodeMetadataCacheOnDemand,
&decoder
)
);
Rufen Sie mit der Methode IWICBitmapDecoder::GetFrame den ersten Frame des Bildes vom Decoder ab.
ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(
decoder->GetFrame(0, &frame)
);
Schritt 5: Erstellen Sie einen WIC-Konverter, und initialisieren Sie ihn
Konvertieren Sie das Bild in das BGRA-Farbformat mit WIC. IWICBitmapFrameDecode wird das native Pixelformat des Bildes zurückgeben (so wie JPEGs in GUID_WICPixelFormat24bppBGR gespeichert werden). Um die Leistung von Direct2D zu optimieren, empfehlen wir Ihnen jedoch eine Konvertierung in WICPixelFormat32bppPBGRA.
Erstellen Sie ein IWICFormatConverter-Objekt mithilfe der Methode IWICImagingFactory::CreateFormatConverter.
ComPtr<IWICFormatConverter> converter; DX::ThrowIfFailed( m_wicFactory->CreateFormatConverter(&converter) );Initialisieren Sie den Formatkonverter zur Verwendung von WICPixelFormat32bppPBGRA, und übergeben Sie das Bitmap-Frame.
DX::ThrowIfFailed( converter->Initialize( frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom // premultiplied BGRA has no paletting, so this is ignored ) );
Die Schnittstelle IWICFormatConverter ist von der Schnittstelle IWICBitmapSource abgeleitet, sodass Sie den Konverter an den Effekt Bitmap-Quelle übergeben können.
Schritt 6: Erstellen Sie einen Effekt, und übergeben Sie eine IWICBitmapSource
Verwenden Sie die Methode CreateEffect, um ein Bitmap Source ID2D1Effect-Objekt unter Verwendung des Direct2D-Gerätekontextes zu erstellen.
Verwenden Sie die Methode ID2D1Effect::SetValue, um die Eigenschaft D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE für den WIC-Formatkonverter festzulegen.
Hinweis
Der Bitmap Source Effekt nimmt keinen Input von der SetInput-Methode wie viele Direct2D-Effekte. 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.
Jetzt, da Sie den Bitmap Source-Effekt haben, können Sie ihn als Eingabe für jeden ID2D1Effect verwenden und einen Effekt-Graphen 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.
}