다음을 통해 공유


FilePicker를 사용하여 Direct2D 효과에 이미지를 로드하는 방법

Windows::Storage::P ickers::FileOpenPicker를 사용하여 Direct2D 효과에 이미지를 로드하는 방법을 보여 줍니다. 사용자가 Windows 스토어 앱의 스토리지에서 이미지 파일을 선택하도록 하려면 FileOpenPicker사용하는 것이 좋습니다.

알아야 하는 작업

기술

필수 조건

지침

1단계: 파일 선택기 열기

FileOpenPicker 개체를 만들고 ViewMode, SuggestedStartLocationFileTypeFilter를 설정하여 이미지를 선택합니다. PickSingleFileAsync 메서드를 호출합니다.

    FileOpenPicker^ openPicker = ref new FileOpenPicker();
    openPicker->ViewMode = PickerViewMode::Thumbnail;
    openPicker->SuggestedStartLocation = PickerLocationId::PicturesLibrary;
    openPicker->FileTypeFilter->Append(".jpg");
    auto pickOperation = openPicker->PickSingleFileAsync();

PickSingleFileAsync가 완료되면 반환되는 IAsyncOperation 인터페이스에서 파일 스트림을 가져옵니다.

2단계: 파일 스트림 가져오기

파일 선택 비동기 작업이 반환된 후 실행할 완료 처리기를 선언합니다. GetResults 메서드를 사용하여 파일을 검색하고 파일 스트림 개체를 가져옵니다.

    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);
                             });
        }
    });

다음 단계에서는 IRandomAccessStream 개체를 WIC전달할 수 있는 IStream으로 변환합니다.

3단계: 파일 스트림 변환

CreateStreamOverRandomAccessStream 함수를 사용하여 파일 스트림을 변환합니다. Windows 런타임 API는 스트림을 나타냅니다.IRandomAccessStream, WIC는 IStream사용합니다.

    ComPtr<IStream> istream;
    DX::ThrowIfFailed(
        CreateStreamOverRandomAccessStream(
        reinterpret_cast<IUnknown*>(fileStream),
        IID_PPV_ARGS(&istream)
        )
    );

참고 항목

CreateStreamOverRandomAccessStream 함수를 사용하려면 프로젝트에 shcore.h를 포함해야 합니다.

 

4단계: WIC 디코더 만들기 및 프레임 가져오기

IWICImagingFactory::CreateDecoderFromStream 메서드를 사용하여 IWICBitmapDecoder 개체를 만듭니다.

    ComPtr<IWICBitmapDecoder> decoder;
    DX::ThrowIfFailed(
          m_wicFactory->CreateDecoderFromStream(
                    istream.Get(),
                    nullptr,
                    WICDecodeMetadataCacheOnDemand,
                    &decoder
                    )
          );

IWICBitmapDecoder::GetFrame 메서드를 사용하여 디코더에서 이미지의 첫 번째 프레임을 가져옵니다.

    ComPtr<IWICBitmapFrameDecode> frame;
    DX::ThrowIfFailed(
        decoder->GetFrame(0, &frame)
        );

5단계: WIC 변환기 만들기 및 초기화

WIC를 사용하여 이미지를 BGRA 색 형식으로 변환합니다. IWICBitmapFrameDecode 는 JPEG가 GUID_WICPixelFormat24bppBGR 저장되는 것처럼 이미지의 네이티브 픽셀 형식을 반환합니다. 그러나 Direct2D를 사용한 성능 최적화에서는 WICPixelFormat32bppPBGRA로 변환하는 것이 좋습니다.

  1. IWICImagingFactory::CreateFormatConverter 메서드를 사용하여 IWICFormatConverter 개체를 만듭니다.

        ComPtr<IWICFormatConverter> converter;
        DX::ThrowIfFailed(
            m_wicFactory->CreateFormatConverter(&converter)
            ); 
    
    
  2. WICPixelFormat32bppPBGRA를 사용하고 비트맵 프레임에 전달하도록 형식 변환기를 초기화합니다.

       DX::ThrowIfFailed(
            converter->Initialize(
                frame.Get(),
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                nullptr,
                0.0f,
                WICBitmapPaletteTypeCustom  // premultiplied BGRA has no paletting, so this is ignored
                )
            );
    

IWICFormatConverter 인터페이스는 IWICBitmapSource 인터페이스에서 파생되므로 변환기를 비트맵 소스 효과에 전달할 수 있습니다.

6단계: 효과 만들기 및 IWICBitmapSource 전달

CreateEffect 메서드를 사용하여 Direct2D 디바이스 컨텍스트사용하여 비트맵 원본 ID2D1Effect 개체를 만듭니다.

ID2D1Effect::SetValue 메서드를 사용하여 D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE 속성을 WIC 형식 변환기로 설정합니다.

참고 항목

비트맵 소스 효과는 많은 Direct2D 효과와 같이 SetInput 메서드의 입력을 받지 않습니다. 대신 IWICBitmapSource 개체가 속성으로 지정됩니다.

 

    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.

이제 비트맵 소스 효과가 있으므로 ID2D1Effect대한 입력으로 사용하고 효과 그래프를 만들 수 있습니다.

전체 예제

다음은 이 예제의 전체 코드입니다.

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.
}