locked
How to draw an image via Direct2D having just an URL?

    Question

  • Hello,

    could someone please provide an example of how to draw an image which is referenced by an url using the direct 2d api.

    How to download the image and how to transport the result down to the DrawBitmap method of the render target?

    Is it possible to reuse the BitmapImage type in C++?

    Thank you in advance

    Regards

    Alex

    Thursday, June 21, 2012 10:57 AM

Answers

  • Here is an example:

    C#:

          HttpClient http = new HttpClient();
          byte[] bytes = await http.GetByteArrayAsync(@"http://.../picture.jpg");
    
          fRenderer.InitializeBackground(bytes, bytes.Length);
    
    C++:
      void InkRendererPanel::InitializeBackground(const Platform::Array<byte>^ bytes, int length)
      {
        Microsoft::WRL::ComPtr<IWICStream> wicStream;
        DX::ThrowIfFailed(
          m_wicFactory->CreateStream(&wicStream)
         );
        
        wicStream->InitializeFromMemory(bytes->Data, length);
    
        Microsoft::WRL::ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
        DX::ThrowIfFailed(
          m_wicFactory->CreateDecoderFromStream(wicStream.Get(), nullptr, 
          WICDecodeMetadataCacheOnDemand,
          &wicBitmapDecoder
          )
          );
    
        Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
        DX::ThrowIfFailed(
          wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
          );
    
        Microsoft::WRL::ComPtr<IWICFormatConverter> wicFormatConverter;
        DX::ThrowIfFailed(
          m_wicFactory->CreateFormatConverter(&wicFormatConverter)
          );
    
        DX::ThrowIfFailed(
          wicFormatConverter->Initialize(
          wicBitmapFrame.Get(),
          GUID_WICPixelFormat32bppPBGRA,
          WICBitmapDitherTypeNone,
          nullptr,
          0.0,
          WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
          )
          );
    
        double dpiX = 96.0f;
        double dpiY = 96.0f;
        DX::ThrowIfFailed(
          wicFormatConverter->GetResolution(&dpiX, &dpiY)
          );
    
        DX::ThrowIfFailed(
          m_d2dContext->CreateBitmapFromWicBitmap(
          wicFormatConverter.Get(),
          BitmapProperties(
          PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
          static_cast<float>(dpiX),
          static_cast<float>(dpiY)
          ),
          &m_logoBitmap
          )
          );
    
        m_logoSize = m_logoBitmap->GetSize();
    
        Render();
      }
    
      void InkRendererPanel::Render()
      {
        m_d2dContext->BeginDraw();
        
        // Render background
        if (m_logoBitmap != nullptr)
        {
          D2D1_RECT_F destinationRect = {0, 0, m_swapChainPanel->ActualWidth, m_swapChainPanel->ActualHeight};
          m_d2dContext->DrawBitmap(m_logoBitmap.Get(), destinationRect);
        }
    
        HRESULT hr = m_d2dContext->EndDraw();
        if (hr == D2DERR_RECREATE_TARGET)
        {
          m_d2dContext->SetTarget(nullptr);
          m_d2dTargetBitmap = nullptr;
          CreateWindowSizeDependentResources();
        }
        else
        {
          DX::ThrowIfFailed(hr);
        }
    
       }
    


    Friday, June 22, 2012 12:37 PM

All replies

  • Direct2D doesn't know anything about URLs. You would need to download the image data through web API. If you are getting a typical image type (jpg, png, bmp, etc.) you can use a BitmapDecoder to convert the stream of bytes into pixel values to use in Direct2D.

    You can also use Xaml from C++, so you could load the image into a WriteableBitmap and then access its pixel data.

    --Rob

    Thursday, June 21, 2012 11:11 PM
    Owner
  • Here is an example:

    C#:

          HttpClient http = new HttpClient();
          byte[] bytes = await http.GetByteArrayAsync(@"http://.../picture.jpg");
    
          fRenderer.InitializeBackground(bytes, bytes.Length);
    
    C++:
      void InkRendererPanel::InitializeBackground(const Platform::Array<byte>^ bytes, int length)
      {
        Microsoft::WRL::ComPtr<IWICStream> wicStream;
        DX::ThrowIfFailed(
          m_wicFactory->CreateStream(&wicStream)
         );
        
        wicStream->InitializeFromMemory(bytes->Data, length);
    
        Microsoft::WRL::ComPtr<IWICBitmapDecoder> wicBitmapDecoder;
        DX::ThrowIfFailed(
          m_wicFactory->CreateDecoderFromStream(wicStream.Get(), nullptr, 
          WICDecodeMetadataCacheOnDemand,
          &wicBitmapDecoder
          )
          );
    
        Microsoft::WRL::ComPtr<IWICBitmapFrameDecode> wicBitmapFrame;
        DX::ThrowIfFailed(
          wicBitmapDecoder->GetFrame(0, &wicBitmapFrame)
          );
    
        Microsoft::WRL::ComPtr<IWICFormatConverter> wicFormatConverter;
        DX::ThrowIfFailed(
          m_wicFactory->CreateFormatConverter(&wicFormatConverter)
          );
    
        DX::ThrowIfFailed(
          wicFormatConverter->Initialize(
          wicBitmapFrame.Get(),
          GUID_WICPixelFormat32bppPBGRA,
          WICBitmapDitherTypeNone,
          nullptr,
          0.0,
          WICBitmapPaletteTypeCustom  // the BGRA format has no palette so this value is ignored
          )
          );
    
        double dpiX = 96.0f;
        double dpiY = 96.0f;
        DX::ThrowIfFailed(
          wicFormatConverter->GetResolution(&dpiX, &dpiY)
          );
    
        DX::ThrowIfFailed(
          m_d2dContext->CreateBitmapFromWicBitmap(
          wicFormatConverter.Get(),
          BitmapProperties(
          PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
          static_cast<float>(dpiX),
          static_cast<float>(dpiY)
          ),
          &m_logoBitmap
          )
          );
    
        m_logoSize = m_logoBitmap->GetSize();
    
        Render();
      }
    
      void InkRendererPanel::Render()
      {
        m_d2dContext->BeginDraw();
        
        // Render background
        if (m_logoBitmap != nullptr)
        {
          D2D1_RECT_F destinationRect = {0, 0, m_swapChainPanel->ActualWidth, m_swapChainPanel->ActualHeight};
          m_d2dContext->DrawBitmap(m_logoBitmap.Get(), destinationRect);
        }
    
        HRESULT hr = m_d2dContext->EndDraw();
        if (hr == D2DERR_RECREATE_TARGET)
        {
          m_d2dContext->SetTarget(nullptr);
          m_d2dTargetBitmap = nullptr;
          CreateWindowSizeDependentResources();
        }
        else
        {
          DX::ThrowIfFailed(hr);
        }
    
       }
    


    Friday, June 22, 2012 12:37 PM