次の方法で共有


FilePicker を使用して Direct2D 効果に画像を読み込む方法

Windows::Storage::Pickers::FileOpenPicker を使用して、イメージを Direct2D 効果に読み込む方法を示します。 ユーザーが Windows ストア アプリのストレージからイメージ ファイルを選択できるようにする場合は、FileOpenPicker を使用することをお勧めします。

知っておくべきこと

テクノロジ

前提条件

  • 効果を作成するには、ID2D1DeviceContext オブジェクトが必要です。
  • WIC オブジェクトを作成するには、IWICImagingFactory オブジェクトが必要です。

手順

手順 1: ファイル ピッカーを開く

FileOpenPicker オブジェクトを作成し、イメージを選択するための ViewModeSuggestedStartLocation、および FileTypeFilter を設定します。 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 オブジェクトを IStream に変換し、WIC に渡すことができます。

手順 3: ファイル ストリームを変換する

CreateStreamOverRandomAccessStream 関数を使用して、ファイル ストリームを変換します。 Windows ランタイム API は、IRandomAccessStream を含むストリームを表します。また、WICIStream を使用します。

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

Note

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 インターフェイスから派生するため、コンバーターを bitmap ソース効果に渡すことができます。

手順 6: 効果を作成して IWICBitmapSource に渡す

CreateEffect メソッドを使用し、Direct2D デバイス コンテキスト を使用して bitmap source ID2D1Effect オブジェクトを作成します。

ID2D1Effect::SetValue メソッドを使用して、D2D1_BITMAPSOURCE_PROP_WIC_BITMAP_SOURCE プロパティを WIC フォーマット コンバーターに設定します。

Note

ビットマップ ソース効果は、多くの 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.
}