Cómo cargar una imagen en efectos de Direct2D mediante FilePicker
Muestra cómo usar Windows::Storage::P ickers::FileOpenPicker para cargar una imagen en efectos de Direct2D. Si quieres permitir que el usuario seleccione un archivo de imagen del almacenamiento en una aplicación de la Tienda Windows, te recomendamos que uses FileOpenPicker.
Lo que necesita saber
Tecnologías
Requisitos previos
- Necesita un objeto ID2D1DeviceContext para crear efectos.
- Necesita un objeto IWICImagingFactory para crear objetos WIC.
Instrucciones
Paso 1: Abrir el selector de archivos
Cree un objeto FileOpenPicker y establezca ViewMode, SuggestedStartLocation y FileTypeFilter para seleccionar imágenes. Llame al método PickSingleFileAsync .
FileOpenPicker^ openPicker = ref new FileOpenPicker();
openPicker->ViewMode = PickerViewMode::Thumbnail;
openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
openPicker->FileTypeFilter->Append(".jpg");
auto pickOperation = openPicker->PickSingleFileAsync();
Una vez que se complete PickSingleFileAsync , obtendrá una secuencia de archivos de la interfaz IAsyncOperation que devuelve.
Paso 2: Obtener una secuencia de archivos
Declare un controlador de finalización para que se ejecute después de que se devuelva la operación asincrónica del selector de archivos. Use el método GetResults para recuperar el archivo y para obtener el objeto de secuencia de archivos.
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);
});
}
});
En el paso siguiente se convierte el objeto IRandomAccessStream en un IStream que se puede pasar a WIC.
Paso 3: Convertir la secuencia de archivos
Use la función CreateStreamOverRandomAccessStream para convertir la secuencia de archivos. Windows Runtime API representan secuencias con IRandomAccessStream, mientras que WIC consume IStream.
ComPtr<IStream> istream;
DX::ThrowIfFailed(
CreateStreamOverRandomAccessStream(
reinterpret_cast<IUnknown*>(fileStream),
IID_PPV_ARGS(&istream)
)
);
Nota:
Para usar la función CreateStreamOverRandomAccessStream , debe incluir shcore.h en el proyecto.
Paso 4: Crear un descodificador WIC y obtener el marco
Cree un objeto IWICBitmapDecoder mediante el método IWICImagingFactory::CreateDecoderFromStream .
ComPtr<IWICBitmapDecoder> decoder;
DX::ThrowIfFailed(
m_wicFactory->CreateDecoderFromStream(
istream.Get(),
nullptr,
WICDecodeMetadataCacheOnDemand,
&decoder
)
);
Obtenga el primer fotograma de la imagen del descodificador mediante el método IWICBitmapDecoder::GetFrame .
ComPtr<IWICBitmapFrameDecode> frame;
DX::ThrowIfFailed(
decoder->GetFrame(0, &frame)
);
Paso 5: Crear un convertidor WIC e inicializar
Convierta la imagen al formato de color BGRA mediante WIC. IWICBitmapFrameDecode devolverá el formato de píxel nativo de la imagen, como los JPEG se almacenan en GUID_WICPixelFormat24bppBGR. Sin embargo, como optimización del rendimiento con Direct2D, se recomienda convertir a WICPixelFormat32bppPBGRA.
Cree un objeto IWICFormatConverter mediante el método IWICImagingFactory::CreateFormatConverter .
ComPtr<IWICFormatConverter> converter; DX::ThrowIfFailed( m_wicFactory->CreateFormatConverter(&converter) );
Inicialice el convertidor de formato para usar WICPixelFormat32bppPBGRA y pase el marco de mapa de bits.
DX::ThrowIfFailed( converter->Initialize( frame.Get(), GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nullptr, 0.0f, WICBitmapPaletteTypeCustom // premultiplied BGRA has no paletting, so this is ignored ) );
La interfaz IWICFormatConverter se deriva de la interfaz IWICBitmapSource , por lo que puede pasar el convertidor al efecto de origen del mapa de bits .
Paso 6: Crear efecto y pasar un IWICBitmapSource
Use el método CreateEffect para crear un objeto ID2D1Effect de origen de mapa de bits mediante el contexto del dispositivoDirect2D.
Use el método ID2D1Effect::SetValue para establecer la propiedad D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE en el convertidor de formatoWIC.
Nota:
El efecto de origen del mapa de bits no toma una entrada del método SetInput como muchos efectos direct2D. En su lugar, el objeto IWICBitmapSource se especifica como una propiedad .
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.
Ahora que tiene el efecto de origen del mapa de bits , puede usarlo como entrada para cualquier ID2D1Effect y crear un gráfico de efectos.
Ejemplo completo
Este es el código completo de este ejemplo.
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.
}
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de