Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. IWinHttpRequest get_ResponseStream and Bitmap FromStream [modified]

IWinHttpRequest get_ResponseStream and Bitmap FromStream [modified]

Scheduled Pinned Locked Moved C / C++ / MFC
graphicswinformshelpquestion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    J B 0
    wrote on last edited by
    #1

    Hi, I am writing some code that can download JPEG images from the net (HTTP) and display them on my dialog app. So far I am able to get the image with IStream interface by using IWinHttpRequest's get_ResponseStream(). But I found myself failing to take the Stream object to load it to GDI+ Bitmap object.

    IStream *pStream; // valid Stream object downloaded
    if (NULL != pStream)
    {
    Bitmap *pGdiBmp = NULL;

    // Rewind IStream.
    LARGE\_INTEGER llMove;
    llMove.LowPart = 0;
    llMove.HighPart = 0;
    pStream->Seek(llMove, STREAM\_SEEK\_SET, NULL);
    pGdiBmp = Bitmap::FromStream(pStream);
    

    }

    pGdiBmp is always NULL. I tried to save pStream to disk and the resulted binary is correct JPEG file. What am I doing wrong here? Any help would be great. Thanks in advance.

    modified on Thursday, May 7, 2009 11:48 AM

    S 1 Reply Last reply
    0
    • J J B 0

      Hi, I am writing some code that can download JPEG images from the net (HTTP) and display them on my dialog app. So far I am able to get the image with IStream interface by using IWinHttpRequest's get_ResponseStream(). But I found myself failing to take the Stream object to load it to GDI+ Bitmap object.

      IStream *pStream; // valid Stream object downloaded
      if (NULL != pStream)
      {
      Bitmap *pGdiBmp = NULL;

      // Rewind IStream.
      LARGE\_INTEGER llMove;
      llMove.LowPart = 0;
      llMove.HighPart = 0;
      pStream->Seek(llMove, STREAM\_SEEK\_SET, NULL);
      pGdiBmp = Bitmap::FromStream(pStream);
      

      }

      pGdiBmp is always NULL. I tried to save pStream to disk and the resulted binary is correct JPEG file. What am I doing wrong here? Any help would be great. Thanks in advance.

      modified on Thursday, May 7, 2009 11:48 AM

      S Offline
      S Offline
      Stuart Dootson
      wrote on last edited by
      #2

      I'd verify that the contents of the stream are a JPEG by loading it into memory using GetHGlobalFromStream followed by a GlobalLock on the HGLOBAL you got back from the first function. Then verify that the memory starts with the string "JFIF". I used the WinHttp functions to download a JPG and found that the JPG started after the first six bytes of the response (I created a stream on a set of bytes) - I needed to offset the stream by six bytes to get the Bitmap to load:

      Gdiplus::Bitmap* LoadBitmapFromUrl(CString const& url)
      {
      HINTERNET hInternet = WinHttpOpen(L"hello", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
      if (!hInternet) return 0;
      HINTERNET hConnection = WinHttpConnect(hInternet, L"www.python.org", INTERNET_DEFAULT_PORT, 0);
      if (!hConnection) return 0;
      LPCWSTR types[] = { L"image/jpeg", 0 };
      HINTERNET hRequest = WinHttpOpenRequest(hConnection, L"GET", L"/images/success/standrews.jpg", 0, WINHTTP_NO_REFERER, types, 0);
      if (!hRequest) return 0;
      if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) return 0;
      if (!WinHttpReceiveResponse(hRequest, 0)) return 0;
      HGLOBAL gblBuffer = GlobalAlloc(0, 1<<20);
      LPBYTE buffer = (LPBYTE)GlobalLock(gblBuffer);
      DWORD nBytesRead;
      if (!WinHttpReadData(hRequest, buffer, 1<<20, &nBytesRead)) return 0;
      IStream* pStream = 0;
      CreateStreamOnHGlobal(gblBuffer, FALSE, &pStream);
      ULARGE_INTEGER size; size.QuadPart = nBytesRead;
      pStream->SetSize(size);
      LARGE_INTEGER offset; offset.QuadPart = 6;
      pStream->Seek(offset, STREAM_SEEK_SET, 0);
      return new Gdiplus::Bitmap(pStream, FALSE);
      }

      (Please ignore the memory leak - I couldn't be bothered to tidy up - it's not production code :-))

      Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

      J 1 Reply Last reply
      0
      • S Stuart Dootson

        I'd verify that the contents of the stream are a JPEG by loading it into memory using GetHGlobalFromStream followed by a GlobalLock on the HGLOBAL you got back from the first function. Then verify that the memory starts with the string "JFIF". I used the WinHttp functions to download a JPG and found that the JPG started after the first six bytes of the response (I created a stream on a set of bytes) - I needed to offset the stream by six bytes to get the Bitmap to load:

        Gdiplus::Bitmap* LoadBitmapFromUrl(CString const& url)
        {
        HINTERNET hInternet = WinHttpOpen(L"hello", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
        if (!hInternet) return 0;
        HINTERNET hConnection = WinHttpConnect(hInternet, L"www.python.org", INTERNET_DEFAULT_PORT, 0);
        if (!hConnection) return 0;
        LPCWSTR types[] = { L"image/jpeg", 0 };
        HINTERNET hRequest = WinHttpOpenRequest(hConnection, L"GET", L"/images/success/standrews.jpg", 0, WINHTTP_NO_REFERER, types, 0);
        if (!hRequest) return 0;
        if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) return 0;
        if (!WinHttpReceiveResponse(hRequest, 0)) return 0;
        HGLOBAL gblBuffer = GlobalAlloc(0, 1<<20);
        LPBYTE buffer = (LPBYTE)GlobalLock(gblBuffer);
        DWORD nBytesRead;
        if (!WinHttpReadData(hRequest, buffer, 1<<20, &nBytesRead)) return 0;
        IStream* pStream = 0;
        CreateStreamOnHGlobal(gblBuffer, FALSE, &pStream);
        ULARGE_INTEGER size; size.QuadPart = nBytesRead;
        pStream->SetSize(size);
        LARGE_INTEGER offset; offset.QuadPart = 6;
        pStream->Seek(offset, STREAM_SEEK_SET, 0);
        return new Gdiplus::Bitmap(pStream, FALSE);
        }

        (Please ignore the memory leak - I couldn't be bothered to tidy up - it's not production code :-))

        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

        J Offline
        J Offline
        J B 0
        wrote on last edited by
        #3

        Dear Stuart, Thanks for the help. I'd get invalid image if I offset the stream by 6 bytes. I am not sure why it worked in your case. Anyway, I found where my problem was. I have that code running outside of GDI+ library init scope. After I moved the following init code to CWinApp::InitInstance(), it worked fine.

        // Initialize GDI+.
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

        S 1 Reply Last reply
        0
        • J J B 0

          Dear Stuart, Thanks for the help. I'd get invalid image if I offset the stream by 6 bytes. I am not sure why it worked in your case. Anyway, I found where my problem was. I have that code running outside of GDI+ library init scope. After I moved the following init code to CWinApp::InitInstance(), it worked fine.

          // Initialize GDI+.
          Gdiplus::GdiplusStartupInput gdiplusStartupInput;
          Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

          S Offline
          S Offline
          Stuart Dootson
          wrote on last edited by
          #4

          I took it as a given that the GDI+ stuff was right - more fool me :-)

          J.B. wrote:

          I'd get invalid image if I offset the stream by 6 bytes. I am not sure why it worked in your case.

          Maybe because I was using WinHttpReadData rather than getting a stream directly from the IWinHttpRequest object.

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          J 1 Reply Last reply
          0
          • S Stuart Dootson

            I took it as a given that the GDI+ stuff was right - more fool me :-)

            J.B. wrote:

            I'd get invalid image if I offset the stream by 6 bytes. I am not sure why it worked in your case.

            Maybe because I was using WinHttpReadData rather than getting a stream directly from the IWinHttpRequest object.

            Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

            J Offline
            J Offline
            J B 0
            wrote on last edited by
            #5

            Stuart Dootson wrote:

            Maybe because I was using WinHttpReadData rather than getting a stream directly from the IWinHttpRequest object.

            That'd be strange, because I checked the my Stream buffer and it had the same pattern as you described - after first 6 bytes, it comes with "JFIF"

            FF D8 FF E0 00 10 4A 46 49 46
            J F I F

            S 1 Reply Last reply
            0
            • J J B 0

              Stuart Dootson wrote:

              Maybe because I was using WinHttpReadData rather than getting a stream directly from the IWinHttpRequest object.

              That'd be strange, because I checked the my Stream buffer and it had the same pattern as you described - after first 6 bytes, it comes with "JFIF"

              FF D8 FF E0 00 10 4A 46 49 46
              J F I F

              S Offline
              S Offline
              Stuart Dootson
              wrote on last edited by
              #6

              I'm wrong - I thought the JFIF came at the start of a JPEG file - having just looked at a JPG in a hex editor, it doesn't.

              Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups