title: Embed PNG (Or Bitmap with alpha channel) in executable
body: <p><strong>TL;DR:</strong> I want to create a standalone application that has image resources (with alpha channel) embedded.  What is the modern/standard way of doing this and extracting the data?</p>
  <p>I am currently writing an application in C++ that uses OpenGL as the graphics engine (I chose it for the faster development time compared to Vulkan, even though I really want to learn Vulkan as well) and in this app I use Signed Distance Fields to render my text.  This requires a Font Atlas with an alpha channel to draw the characters from.</p>
  <p>I want to be able to embed this Font Atlas (currently it is a .PNG file) in the executable.  There are other image resources as well, but I am mentioning this scenario to show why I really need the alpha channel.</p>
  <hr />
  <p>I used the Win32 API to do the following:</p>
  <h2>Get current module.</h2>
  <pre><code>HMODULE getCurrentModule()
  {
      HMODULE hModule = NULL;
      GetModuleHandleEx(
          GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
          (LPCTSTR)getCurrentModule,
          &amp;hModule);
      return hModule;
  }
  </code></pre>
  <h2>Embed Text files for the shaders.</h2>
  <pre><code>std::string loadShaderFromResource(int shaderID) 
  {
      // Load resource from executable.
      HRSRC shaderResource = FindResource(getCurrentModule(), MAKEINTRESOURCE(shaderID), MAKEINTRESOURCE(TEXTFILE));
      HGLOBAL resourceData = LoadResource(getCurrentModule(), shaderResource);
      DWORD resourceSize = SizeofResource(getCurrentModule(), shaderResource);
      char* resourceFinal = (char*)LockResource(resourceData);
      std::string shaderSource;
      shaderSource.assign(resourceFinal, resourceSize);
      return shaderSource;
  }
  </code></pre>
  <h2>My resource.h file.</h2>
  <p><em>It is a bit messy, but I am including it to provide as much info as possible.</em></p>
  <pre><code>/*=======================================================================================================================================*/
  /* Setup by Visual Studio.                                                                                                               */
  /*=======================================================================================================================================*/
  
  // Next default values for new objects
  // 
  #ifdef APSTUDIO_INVOKED
  #ifndef APSTUDIO_READONLY_SYMBOLS
  #define _APS_NEXT_RESOURCE_VALUE        116
  #define _APS_NEXT_COMMAND_VALUE         40003
  #define _APS_NEXT_CONTROL_VALUE         1001
  #define _APS_NEXT_SYMED_VALUE           101
  #endif
  #endif
  
  /*=======================================================================================================================================*/
  /* Resources.                                                                                                                            */
  /*=======================================================================================================================================*/
  
  //-------------------------------------------------------------------------------------------------
  // Resource Types
  #define TEXTFILE 255
  #define PNG 254
  //-------------------------------------------------------------------------------------------------
  // Shaders
  #define BASIC_SHADER 253
  #define STATIC_SHADER 252
  #define TEXTURE_SHADER 251
  //-------------------------------------------------------------------------------------------------
  // ImGui images.
  #define COMPONENT_PNG 250               
  #define DRAW_CIRCUIT_BUCKETS 249
  #define DRAW_MCC_PNG 248                
  //-------------------------------------------------------------------------------------------------
  // OpenGL Textures.
  #define CIRCUIT_TREE_PNG 247
  //-------------------------------------------------------------------------------------------------
  // OpenGL Fonts. 
  #define ARIAL_SDF_FNT 246       
  #define ARIAL_SDF_PNG 245       
  #define ARIAL_SDF_BMP 244
  #define ARIAL_SDF_MIN_FNT 243
  #define ARIAL_SDF_MIN_PNG 242   
  //-------------------------------------------------------------------------------------------------
  // Application icon.
  #define IDI_ICON1 116           // Exe icon.
  #define ICON_BMP 115            // GLFW icon.
  #define PANDA 114
  //-------------------------------------------------------------------------------------------------
  
  /*=======================================================================================================================================*/
  /* Includes.                                                                                                                             */
  /*=======================================================================================================================================*/
  
  // Windows api for the exe.
  #include &lt;Windows.h&gt;
  #include &lt;string&gt;
  
  /*=======================================================================================================================================*/
  /* Data.                                                                                                                                 */
  /*=======================================================================================================================================*/
  
  // Struct that stores the bitmap data.
  struct Bitmap {
      void* pixelData;
      int width = 0;
      int height = 0;
  };
  
  /*=======================================================================================================================================*/
  /* Functions.                                                                                                                            */
  /*=======================================================================================================================================*/
  
  // Load the current module.
  HMODULE getCurrentModule();
  
  // Load shader from resource.
  std::string loadShaderFromResource(int shaderID);
  
  // Loading bitmaps.
  Bitmap loadBitmapFromResource(int bitmapID);
  unsigned int loadBitmapToGL(Bitmap bitmap);
  
  
  /*=======================================================================================================================================*/
  /* EOF.                                                                                                                                  */
  /*=======================================================================================================================================*/
  </code></pre>
  <h2>My resource.rc file.</h2>
  <pre><code>// Microsoft Visual C++ generated resource script.
  //
  #include &quot;resource.h&quot;
  
  #define APSTUDIO_READONLY_SYMBOLS
  /////////////////////////////////////////////////////////////////////////////
  //
  // Generated from the TEXTINCLUDE 2 resource.
  //
  #include &quot;winres.h&quot;
  
  /////////////////////////////////////////////////////////////////////////////
  #undef APSTUDIO_READONLY_SYMBOLS
  
  /////////////////////////////////////////////////////////////////////////////
  // English (United States) resources
  
  #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
  LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
  #pragma code_page(1252)
  
  #ifdef APSTUDIO_INVOKED
  /////////////////////////////////////////////////////////////////////////////
  //
  // TEXTINCLUDE
  //
  
  1 TEXTINCLUDE
  BEGIN
  &quot;resource.h\0&quot;
  END
  
  2 TEXTINCLUDE
  BEGIN
  &quot;#include &quot;&quot;winres.h&quot;&quot;\r\n&quot;
  &quot;\0&quot;
  END
  
  3 TEXTINCLUDE
  BEGIN
  &quot;\r\n&quot;
  &quot;\0&quot;
  END
  
  #endif    // APSTUDIO_INVOKED
  
  /*=======================================================================================================================================*/
  /* Resources.                                                                                                                            */
  /*=======================================================================================================================================*/
  
  //-------------------------------------------------------------------------------------------------
  // Resource ID                  Resource Type               Resource Path
  //-------------------------------------------------------------------------------------------------
  // Application icon.
  IDI_ICON1                       ICON                        &quot;Icons\\circuitIcon128.ico&quot;
  ICON_BMP                        BITMAP                      &quot;Icons\\circuitIcon.bmp&quot;
  PANDA                           BITMAP                      &quot;Icons\\panda.bmp&quot;
  //-------------------------------------------------------------------------------------------------
  // Shaders.
  BASIC_SHADER                    TEXTFILE                    &quot;Shaders\\basicShader.shader&quot;
  STATIC_SHADER                   TEXTFILE                    &quot;Shaders\\staticShader.shader&quot;
  TEXTURE_SHADER                  TEXTFILE                    &quot;Shaders\\textureShader.shader&quot;
  //-------------------------------------------------------------------------------------------------
  // ImGui images.
  COMPONENT_PNG                   PNG                         &quot;Icons\\component.png&quot;
  DRAW_CIRCUIT_BUCKETS_PNG        PNG                         &quot;Icons\\Draw_Circuit_Buckets.png&quot;
  DRAW_MCC_PNG                    PNG                         &quot;Icons\\Draw_MCC.png&quot;
  //-------------------------------------------------------------------------------------------------
  // OpenGL Textures.
  CIRCUIT_TREE_PNG                PNG                         &quot;Textures\\circuitTree.png&quot;
  //-------------------------------------------------------------------------------------------------
  // OpenGL Fonts. 
  ARIAL_SDF_FNT                   TEXTFILE                    &quot;Fonts\\Arial_SDF.fnt&quot;
  ARIAL_SDF_PNG                   PNG                         &quot;Fonts\\Arial_SDF_PNG.png&quot;
  ARIAL_SDF_BMP                   BITMAP                      &quot;Fonts\\Arial_SDF_BMP_32.bmp&quot;
  ARIAL_SDF_MIN_FNT               TEXTFILE                    &quot;Fonts\\Arial_SDF_Min.fnt&quot;
  ARIAL_SDF_MIN_PNG               PNG                         &quot;Fonts\\Arial_SDF_Min.png&quot;
  //-------------------------------------------------------------------------------------------------
  
  #endif    // English (United States) resources
  
  //=================================================================================================
  
  #ifndef APSTUDIO_INVOKED
  /////////////////////////////////////////////////////////////////////////////
  //
  // Generated from the TEXTINCLUDE 3 resource.
  //
  
  
  /////////////////////////////////////////////////////////////////////////////
  #endif    // not APSTUDIO_INVOKED
   /*=======================================================================================================================================*/
  /* EOF.                                                                                                                                  */
  /*=======================================================================================================================================*/
  </code></pre>
  <hr />
  <p>I noticed that most of the forums regarding the Win32 API and this type of question is very, very old.  Is it still used?  Is there a more modern way of doing it?  I saw some people using CMake.</p>
  <hr />
  <h2>Edit 1</h2>
  <p>I tried adding the following, as suggested by @Barmak with some edits:</p>
  <pre><code>HBITMAP loadImageFromResource(int resourceID)
  {
      HBITMAP hbitmap = NULL;
      ULONG_PTR token;
      Gdiplus::GdiplusStartupInput tmp;
      Gdiplus::GdiplusStartup(&amp;token, &amp;tmp, NULL);
      if (auto hres = FindResource(getCurrentModule(), MAKEINTRESOURCE(resourceID), RT_RCDATA))
          if (auto size = SizeofResource(getCurrentModule(), hres))
              if (auto data = LockResource(LoadResource(getCurrentModule(), hres)))
                  if (auto stream =  SHCreateMemStream((BYTE*)data, size))
                  {
                      Gdiplus::Bitmap bmp(stream);
                      stream-&gt;Release();
                      bmp.GetHBITMAP(Gdiplus::Color::Transparent, &amp;hbitmap);
                  }
      Gdiplus::GdiplusShutdown(token);
      return hbitmap;
  }
  </code></pre>
  <p>However, when viewing <code>hbitmap</code> in debug mode it shows <code>0xffffffffa00513d7 {unused=???}</code> and does not work.</p>
  <p>resource.h:</p>
  <pre><code>#define ICON_PNG 240            // GLFW icon.
  </code></pre>
  <p>resource.rc:</p>
  <pre><code>ICON_PNG                        RCDATA                      &quot;Icons\\circuitImage.png&quot;
  </code></pre>
  <hr />
  <h2>Edit 2</h2>
  <p>I made a simple mistake.  I added these lines to the function:</p>
  <pre><code>BITMAP bitmap;
  GetObject(hbitmap, sizeof(BITMAP), &amp;bitmap);
  </code></pre>
  <p>And now it works by returing a BITMAP instead of HBITMAP.  However, it is upside down and some of the coloring seems off when using it with <code>glfwSetWindowIcon()</code>.  It works perfectly in other places!</p>
  <pre><code>BITMAP loadImageFromResource(int resourceID)
  {
      HBITMAP hbitmap = NULL;
      ULONG_PTR token;
      Gdiplus::GdiplusStartupInput tmp;
      Gdiplus::GdiplusStartup(&amp;token, &amp;tmp, NULL);
      if (auto hres = FindResource(getCurrentModule(), MAKEINTRESOURCE(resourceID), RT_RCDATA))
          if (auto size = SizeofResource(getCurrentModule(), hres))
              if (auto data = LockResource(LoadResource(getCurrentModule(), hres)))
                  if (auto stream =  SHCreateMemStream((BYTE*)data, size))
                  {
                      Gdiplus::Bitmap bmp(stream);
                      stream-&gt;Release();
                      bmp.GetHBITMAP(Gdiplus::Color::Transparent, &amp;hbitmap);
                  }
      Gdiplus::GdiplusShutdown(token);
      BITMAP bitmap;
      GetObject(hbitmap, sizeof(BITMAP), &amp;bitmap);
      return bitmap;
  }
  </code></pre>