Lesson5 AsyncLoad

画像の読み込みを非同期で行います。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. PhotoAdjustment.sln から起動して、Lesson5.AsyncLoad を右クリックします。
    メニューから「スタートアップ プロジェクトに設定」を選びます。
    そのまま右三角アイコンでコンパイル&実行して下さい。
    ウインドウサイズに合わせて、イメージが描画されます。
    Lesson2 と同様にマウスの中ボタンを回転すると画像が拡大します。
    マウスのドラッグで描画範囲を操作することが出来ます。
  2. PhotoRenderer.cpp をダブルクリックして、ソースコードを表示して下さい。
    Lesson5 の Constructor からは沢山のメンバーオブジェクトの Constructor を呼び出しています。
    PhotoRenderer::PhotoRenderer() :
        // Initialize defaults for the transformation variables.
        m_viewPosition(),
        m_zoom(1.0f),
        m_minZoom(1.0f), // Min zoom is dynamically calculated
        m_thumbnailPixelSize(),
        m_thumbnailSize(),
        m_imagePixelSize(),
        m_imageSize(),
        m_contextSize(),
        m_isWindowClosed(false),
        m_renderingMode(RenderingMode::WaitForEvents),
        m_recenterStartZoom(),
        m_recenterStartPosition(),
        m_imageLoaded(false)
    {   m_timer = ref new BasicTimer();  }
    
  3. Run() メソッドは Lesson2 と同じで、レンダリングループが設定されています。
    void PhotoRenderer::Run()
    {
        Render();
    
        while (!m_isWindowClosed)
        {
            switch (m_renderingMode)
            {
                case RenderingMode::WaitForEvents:
                    m_window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
                    break;
    
                case RenderingMode::RunRecenterAnimation:
                    m_window->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
                    UpdateRecenterAnimation();
                    Render();
                    break;
            }
        }
    }
    
  4. Image を描画する Render() メソッドも Lesson2 と同じです。
    void PhotoRenderer::Render()
    {
        m_d2dContext->BeginDraw();
    
        m_d2dContext->DrawImage(
            m_2dTransformEffect.Get(),
            D2D1_INTERPOLATION_MODE_LINEAR,
            D2D1_COMPOSITE_MODE_SOURCE_COPY
            );
    
        HRESULT hr = m_d2dContext->EndDraw();
        if (hr != D2DERR_RECREATE_TARGET)
        {
            DX::ThrowIfFailed(hr);
        }
    
        m_sampleOverlay->Render();
    
        Present();
    }
    
  5. CreateBackgroundDeviceResources() から task を起動して、画像ファイルをロードする BackgroundProcessing(); を呼び出します。
    void PhotoRenderer::CreateBackgroundDeviceResources()
    {
            ・・・
    
        auto backgroundTask = task([this]()
        {
            BackgroundProcessing();
        }).then([this]() {
            // After background processing has completed, change devices so
            // that the background device is now being drawn from. Because
            // this happens on the UI thread, there is no race condition.
            ChangeDevices();
    
            // After the change, force a render to display the full-res image.
            Render();
        }, task_continuation_context::use_current()); // Force render to occur on UI thread.
    }
    
  6. 画像ファイル("mammoth.jpg")をロードする BackgroundProcessing(); です。
    void PhotoRenderer::BackgroundProcessing()
    {
        ComPtr WICFormatConverter;
        CreateWICBitmapSourceFromFilename("mammoth.jpg", &WICFormatConverter, &m_imagePixelSize);
    
        // Create and initialize a BitmapSource effect.
        DX::ThrowIfFailed(m_d2dContextB->CreateEffect(CLSID_D2D1BitmapSource, &m_fullResBitmapSourceEffect));
    
            ・・・
            
    }        
    

超初心者のプログラム入門(DirectX Store)