How to Create a Decoder Using a Stream

This topic describes how to create a bitmap decoder by using a stream.

To create a bitmap decoder by using a stream

  1. Load an image file into a stream. In this example, a stream is created for an application resource.

    In the application resource definition (.rc) file, define the resource. The following example defines an Image resource named IDR_SAMPLE_IMAGE.

    IDR_SAMPLE_IMAGE IMAGE "turtle.jpg"
    

    The resource will be added to the application's resources when the application is built.

  2. Load the resource from the application.

    HRESULT hr = S_OK;
    
    // WIC interface pointers.
    IWICStream *pIWICStream = NULL;
    IWICBitmapDecoder *pIDecoder = NULL;
    IWICBitmapFrameDecode *pIDecoderFrame = NULL;
    
    // Resource management.
    HRSRC imageResHandle = NULL;
    HGLOBAL imageResDataHandle = NULL;
    void *pImageFile = NULL;
    DWORD imageFileSize = 0;
    
    // Locate the resource in the application's executable.
    imageResHandle = FindResource(
       NULL,             // This component.
       L"SampleImage",   // Resource name.
       L"Image");        // Resource type.
    
    hr = (imageResHandle ? S_OK : E_FAIL);
    
    // Load the resource to the HGLOBAL.
    if (SUCCEEDED(hr)){
       imageResDataHandle = LoadResource(NULL, imageResHandle);
       hr = (imageResDataHandle ? S_OK : E_FAIL);
    }
    
    
  3. Lock the resource and get the size.

    // Lock the resource to retrieve memory pointer.
    if (SUCCEEDED(hr)){
       pImageFile = LockResource(imageResDataHandle);
       hr = (pImageFile ? S_OK : E_FAIL);
    }
    
    // Calculate the size.
    if (SUCCEEDED(hr)){
       imageFileSize = SizeofResource(NULL, imageResHandle);
       hr = (imageFileSize ? S_OK : E_FAIL);
    }
    
    
  4. Create an IWICImagingFactory to create Windows Imaging Component (WIC) objects.

    // Create WIC factory
    hr = CoCreateInstance(
        CLSID_WICImagingFactory,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&m_pIWICFactory)
        );
    
  5. Use the CreateStream method to create an IWICStream object and initialize it by using the image memory pointer.

    // Create a WIC stream to map onto the memory.
    if (SUCCEEDED(hr)){
       hr = m_pIWICFactory->CreateStream(&pIWICStream);
    }
    
    // Initialize the stream with the memory pointer and size.
    if (SUCCEEDED(hr)){
       hr = pIWICStream->InitializeFromMemory(
             reinterpret_cast<BYTE*>(pImageFile),
             imageFileSize);
    }
    
  6. Create an IWICBitmapDecoder from the new stream object using the CreateDecoderFromStream method.

    // Create a decoder for the stream.
    if (SUCCEEDED(hr)){
       hr = m_pIWICFactory->CreateDecoderFromStream(
          pIWICStream,                   // The stream to use to create the decoder
          NULL,                          // Do not prefer a particular vendor
          WICDecodeMetadataCacheOnLoad,  // Cache metadata when needed
          &pIDecoder);                   // Pointer to the decoder
    }
    
  7. Get the first IWICBitmapFrameDecode of the image.

    // Retrieve the first bitmap frame.
    if (SUCCEEDED(hr))
    {
       hr = pIDecoder->GetFrame(0, &pIDecoderFrame);
    }
    

    The JPEG file format only supports a single frame. Because the file in this example is a JPEG file, the first frame (0) is used. For image formats that have multiple frames, see How to Retrieve the Frames of an Image for accessing each frame of the image.

  8. Process the image frame. For additional information about IWICBitmapSource objects, see the Bitmap Sources Overview.

See Also

Programming Guide

Reference

Samples