CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6

Hybrid View

  1. #1
    Join Date
    Oct 2013
    Posts
    3

    Screenshot to base64 string

    Hi, I have a problem when I try to convert the buffer of the image into a base64 string. Here is the code:

    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <gdiplus.h>
    #include "ScreenCap.h"
    #include <wchar.h>
    #include "base64.h"
    #include <sstream>
    
    using namespace Gdiplus;
    
    int GetEncoderClsid(WCHAR *format, CLSID *pClsid)
    {
    	unsigned int num = 0,  size = 0;
    	GetImageEncodersSize(&num, &size);
    	if(size == 0) return -1;
    	ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size));
    	if(pImageCodecInfo == NULL) return -1;
    	GetImageEncoders(num, size, pImageCodecInfo);
    	for(unsigned int j = 0; j < num; ++j){
    		if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){
    			*pClsid = pImageCodecInfo[j].Clsid;
    			free(pImageCodecInfo);
    			return j;
    		}    
    	}
    	free(pImageCodecInfo);
    	return -1;
    }
    
    std::string GetScreeny(ULONG uQuality)
    {
    	//this work ---->
        ULONG_PTR gdiplusToken;
    	GdiplusStartupInput gdiplusStartupInput;
    	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
    	
    	HDC hdcScreen  = CreateDC("DISPLAY", NULL, NULL, NULL);
    	HDC hdcCapture = CreateCompatibleDC(hdcScreen);
    	int nWidth     = GetDeviceCaps(hdcScreen, HORZRES),
    	    nHeight    = GetDeviceCaps(hdcScreen, VERTRES),
    	    nBPP       = GetDeviceCaps(hdcScreen, BITSPIXEL);
    	
    	LPBYTE lpCapture;
    	BITMAPINFO bmiCapture = { {
    		sizeof(BITMAPINFOHEADER), nWidth, -nHeight, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0,
    	} };
    	HBITMAP hbmCapture = CreateDIBSection(hdcScreen, &bmiCapture,
    		DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0);
    	if(!hbmCapture){
    		DeleteDC(hdcCapture);
    		DeleteDC(hdcScreen);
    		GdiplusShutdown(gdiplusToken);
    	}
    	
    	int nCapture = SaveDC(hdcCapture);
    	SelectObject(hdcCapture, hbmCapture);
    	BitBlt(hdcCapture, 0, 0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY);
    	RestoreDC(hdcCapture, nCapture);
    	DeleteDC(hdcCapture);
    	DeleteDC(hdcScreen);
    	
    	CLSID imageCLSID;
    	Bitmap *pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL);
    	EncoderParameters encoderParams;
    	encoderParams.Count = 1;
    	encoderParams.Parameter[0].NumberOfValues = 1;
    	encoderParams.Parameter[0].Guid  = EncoderQuality;
    	encoderParams.Parameter[0].Type  = EncoderParameterValueTypeLong;
    	encoderParams.Parameter[0].Value = &uQuality;
    
    	GetEncoderClsid(L"image/jpeg", &imageCLSID);
    	//<----- until here
    
    	IStream *pStream = NULL;
        LARGE_INTEGER liZero = {};
        ULARGE_INTEGER pos = {};
        STATSTG stg = {};
        ULONG bytesRead=0;
        HRESULT hrRet=S_OK;
    
        BYTE* buffer = NULL;  // this is your buffer that will hold the jpeg bytes
        DWORD dwBufferSize = 0;  // this is the size of that buffer;
    
    
        hrRet = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
        hrRet = pScreenShot->Save(pStream, &imageCLSID, &encoderParams) == 0 ? S_OK : E_FAIL;
        hrRet = pStream->Seek(liZero, STREAM_SEEK_SET, &pos);
        hrRet = pStream->Stat(&stg, STATFLAG_NONAME);
    
        // allocate a byte buffer big enough to hold the jpeg stream in memory
        buffer = new BYTE[stg.cbSize.QuadPart];
        hrRet = (buffer == NULL) ? E_OUTOFMEMORY : S_OK;
        dwBufferSize = stg.cbSize.QuadPart;
    
        // copy the stream into memory
        hrRet = pStream->Read(buffer, stg.cbSize.QuadPart, &bytesRead);
    
        // now go save "buffer" and "dwBufferSize" off somewhere.  This is the jpeg buffer
        // don't forget to free it when you are done
    
        // After success or if any of the above calls fail, don't forget to release the stream
    	std::string encodedstring = base64_encode(buffer, dwBufferSize);
        if (pStream)
        {
            pStream->Release();
        }
    
    	delete pScreenShot;
    	DeleteObject(hbmCapture);
    	GdiplusShutdown(gdiplusToken);
    	return encodedstring;
    }
    The base64 code is here: http://www.adp-gmbh.ch/cpp/common/base64.html

    Code run but the output is wrong. I think the problem is "std::string encodedstring = base64_encode(buffer, dwBufferSize);" but I can't figure the solution. Any idea? Thanks.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Screenshot to base64 string

    Quote Originally Posted by Brain_Storm View Post
    Hi, I have a problem when I try to convert the buffer of the image into a base64 string. Here is the code:
    ...
    Is this case you chose a wrong Forum which is for
    Visual C++ Bugs & Fixes
    Share bugs and fixes for source code on this site. Also use this to share bugs/fixes in the various class libraries etc. of use to VC++ developers. This is NOT for general programming questions.
    Quote Originally Posted by Brain_Storm View Post
    Code run but the output is wrong. I think the problem is "std::string encodedstring = base64_encode(buffer, dwBufferSize);" but I can't figure the solution. Any idea? Thanks.
    Did you try to debug your code?
    Victor Nijegorodov

  3. #3
    Join Date
    Oct 2013
    Posts
    3

    Re: Screenshot to base64 string

    Sorry, I thought wrong. I'm newbie of c++ programming. I use Visual Studio 2010.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Screenshot to base64 string

    You are setting hrRet in several places, but never testing this for failure.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Oct 2013
    Posts
    3

    Re: Screenshot to base64 string

    Suggestion?

  6. #6
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Screenshot to base64 string

    Quote Originally Posted by Brain_Storm View Post
    Suggestion?
    Three, so far:
    1. Move this to the appropriate forum.
    2. Debug.
    3. Check the return values from API calls.
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured