CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: can i convert HBITMAP to istream?

  1. #1
    Join Date
    Apr 2009
    Posts
    1,298

    can i convert HBITMAP to istream?

    i need overloading the << and >> input/output operators. but for that i need the HBITMAP like a *.bmp file format.
    so how can i convert the HBITMAP to istream or char*?

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

    Re: can i convert HBITMAP to istream?

    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++17 Compiler: Microsoft VS2019 (16.6.5)

  3. #3
    Join Date
    Apr 2009
    Posts
    1,298

    Re: can i convert HBITMAP to istream?

    i have found these function:
    http://www.codeguru.com/cpp/g-m/bitm...a-BMP-file.htm

    Code:
    // WriteDIB        - Writes a DIB to file
        // Returns        - TRUE on success
        // szFile        - Name of file to write to
        // hDIB            - Handle of the DIB
        BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB)
        {
            BITMAPFILEHEADER    hdr;
            LPBITMAPINFOHEADER    lpbi;
         
            if (!hDIB)
                return FALSE;
         
            CFile file;
            if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
                return FALSE;
         
            lpbi = (LPBITMAPINFOHEADER)hDIB;
         
            int nColors = 1 << lpbi->biBitCount;
         
            // Fill in the fields of the file header 
            hdr.bfType        = ((WORD) ('M' << 8) | 'B');    // is always "BM"
            hdr.bfSize        = GlobalSize (hDIB) + sizeof( hdr );
            hdr.bfReserved1     = 0;
            hdr.bfReserved2     = 0;
            hdr.bfOffBits        = (DWORD) (sizeof( hdr ) + lpbi->biSize +
                                nColors * sizeof(RGBQUAD));
         
            // Write the file header 
            file.Write( &hdr, sizeof(hdr) );
         
            // Write the DIB header and the bits 
            file.Write( lpbi, GlobalSize(hDIB) );
         
            return TRUE;
        }
    i understand the CFILE.... but i don't understand the HANDLE hDIB... it's the HBITMAP?

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    19,757

    Re: can i convert HBITMAP to istream?

    Quote Originally Posted by Cambalinho View Post
    ... i understand the CFILE.... but i don't understand the HANDLE hDIB... it's the HBITMAP?
    Did you only read the code and omit readin the article text?
    Well, then read about the DIB in MSDN: Device-Independent Bitmaps
    Victor Nijegorodov

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,607

    Re: can i convert HBITMAP to istream?

    Quote Originally Posted by Cambalinho View Post
    i need overloading the << and >> input/output operators. but for that i need the HBITMAP like a *.bmp file format.
    so how can i convert the HBITMAP to istream or char*?
    HBITMAP is not a GDI bitmap object, it's just a handle. GDI bitmap object is not a *.bmp file. In case you need a BMP file stream to be created by a bitmap handle, you need to get GDI bitmap object by its handle and save the one to a buffer in accordance with BMP format. When you have it saved to a buffer, the buffer can be transferred to file stream.
    Last edited by Igor Vartanov; July 13th, 2016 at 04:42 PM.
    Best regards,
    Igor

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,607

    Re: can i convert HBITMAP to istream?

    Saving GDI bitmap to IStream using ATL::CImage class:
    Code:
    BOOL BitmapToStream(HBITMAP hbm, IStream **ppStream)
    {
        if (hbm == NULL)
            return FALSE;
    
        CImage   img;
        IStream* ps = NULL;
        HRESULT  hr = CreateStreamOnHGlobal(NULL, TRUE, &ps);
    
        if (FAILED(hr))
            return FALSE;
    
        img.Attach(hbm);
        hr = img.Save(ps, Gdiplus::ImageFormatBMP);
        if (FAILED(hr))
        {
            ps->Release();
            return FALSE;
        }
    
        *ppStream = ps;
        return TRUE;
    }
    Attached Files Attached Files
    Best regards,
    Igor

  7. #7
    Join Date
    Apr 2009
    Posts
    1,298

    Re: can i convert HBITMAP to istream?

    i don't use MFC... sorry.
    but see my istream:
    Code:
    friend std::istream& operator >> (std::istream& lhs, BitmapDC &hBitmap)
        {
            MessageBox("read it");
            BITMAPFILEHEADER bfh = {0};
            lhs.read((char*)&bfh, sizeof(bfh));
    
            BITMAPINFOHEADER bmpInfoHeader = {0};
            bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
            lhs.read((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
            BYTE* pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
            lhs.read((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
            hBitmap.init(bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
            SetDIBitsToDevice(hBitmap.hdcbitmap, 0, 0, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, 0, 0, 0, bmpInfoHeader.biHeight, pBitmapBits,(BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
            BitBlt(GetWindowDC(ActivatedForm), 200, 100, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, hBitmap.hdcbitmap, 0, 0, SRCCOPY);
            delete []pBitmapBits;
            return lhs;
        }
    heres how i use it:
    Code:
    ifstream ReadOnFile(FileName.c_str(), ios::in | ios::binary);
            ReadOnFile >>(char*) bitmapcurrent;
            ReadOnFile.close();
    maybe i miss understood the istream, because the istream& operator >>() isn't called
    what i'm doing wrong?

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,607

    Re: can i convert HBITMAP to istream?

    Quote Originally Posted by Cambalinho View Post
    i don't use MFC... sorry.
    Me neither. Where did you find MFC in the sample I provided? You meant ATL, right? Well, try Gdiplus instead.

    what i'm doing wrong?
    I'll tell what you're doing wrong. You are too much focused on the concepts you came up with. You do not bother about understanding solutions and recommendationd the other guys provide you with. You're not enough careful about reading documentation. And you are relying too much on advices you get on public forums, this one in particular. Try to ask less and work yourself more.
    Best regards,
    Igor

  9. #9
    Join Date
    Apr 2009
    Posts
    1,298

    Re: can i convert HBITMAP to istream?

    sorry Igor. i found my error. and yes, was my own error.
    sometimes i faill simple things that i don't see them(even on work). maybe i will learn 'traning' my brain for avoid more that type of mistakes.
    heres the correct code:
    Code:
    //write HBITMAP:
        friend std::ostream& operator << (std::ostream& lhs, BitmapDC &hBitmap)
        {
            //get hbitmap size:
            BITMAP bm;
            GetObject(hBitmap.bitmapcurrent, sizeof(BITMAP), &bm);
            LONG lWidth=bm.bmWidth;
            LONG lHeight=bm.bmHeight;
            BYTE* pBitmapBits;
            WORD wBitsPerPixel=bm.bmBitsPixel;
            unsigned long pixel_data_size = lHeight * ( ( lWidth * ( wBitsPerPixel / 8 ) ) + 0 );
            // Some basic bitmap parameters
            unsigned long headers_size = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER );
    
            BITMAPINFOHEADER bmpInfoHeader = {0};
    
            // Set the size
            bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    
            // Bit count
            bmpInfoHeader.biBitCount = wBitsPerPixel;
    
            // Use all colors
            bmpInfoHeader.biClrImportant = 0;
    
            // Use as many colors according to bits per pixel
            bmpInfoHeader.biClrUsed = 0;
    
            // Store as un Compressed
            bmpInfoHeader.biCompression = BI_RGB;
    
            // Set the height in pixels
            bmpInfoHeader.biHeight = lHeight;
    
            // Width of the Image in pixels
            bmpInfoHeader.biWidth = lWidth;
    
            // Default number of planes
            bmpInfoHeader.biPlanes = 1;
    
            // Calculate the image size in bytes
            bmpInfoHeader.biSizeImage = pixel_data_size;
    
            //getting the HBitmap pixel data from HDC:
            pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
            GetDIBits(hBitmap.hdcbitmap , hBitmap.bitmapcurrent, 0, bm.bmHeight, pBitmapBits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
    
            BITMAPFILEHEADER bfh = {0};
    
            // This value should be values of BM letters i.e 0x4D42
            // 0x4D = M 042 = B storing in reverse order to match with endian
            bfh.bfType = 0x4D42;
            //bfh.bfType = 'B'+('M' << 8);
    
            // <<8 used to shift ‘M’ to end  */
    
            // Offset to the RGBQUAD
            bfh.bfOffBits = headers_size;
    
            // Total size of image including size of headers
            bfh.bfSize =  headers_size +  bmpInfoHeader.biSizeImage ;
    
            // Write the File header:
            lhs.write((char*)&bfh, sizeof(bfh));
    
            //Write the bitmap info header:
            lhs.write((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
    
            //write pixel data:
            lhs.write((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
    
            delete []pBitmapBits;
    
            return lhs;
        }
    
        //read HBITMAP:
        friend std::istream& operator >> (std::istream& lhs, BitmapDC &hBitmap)
        {
            BITMAPFILEHEADER bfh = {0};
            lhs.read((char*)&bfh, sizeof(bfh));
            BITMAPINFOHEADER bmpInfoHeader = {0};
            bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
            lhs.read((char*)&bmpInfoHeader,sizeof(bmpInfoHeader));
            BYTE* pBitmapBits=new BYTE[bmpInfoHeader.biSizeImage];
            lhs.read((char*)pBitmapBits, bmpInfoHeader.biSizeImage);
            hBitmap.init(bmpInfoHeader.biWidth, bmpInfoHeader.biHeight);
            SetDIBitsToDevice(hBitmap.hdcbitmap, 0, 0, bmpInfoHeader.biWidth, bmpInfoHeader.biHeight, 0, 0, 0, bmpInfoHeader.biHeight, pBitmapBits,(BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
            delete []pBitmapBits;
            return lhs;
        }
    please let me ask a diferent thing: see these class:
    Code:
    struct user
    {
        string name;//C++ type
        int age;
        image foto;//my own class
    
        friend std::ostream& operator << (std::ostream& lhs, user &userTest)
        {
            lhs << userTest.name << userTest.age << userTest.foto;
        }
    
        friend std::istream& operator >> (std::istream& lhs, user &userTest)
        {
            lhs >> userTest.name >> userTest.age >> userTest.foto;
        }
    };
    (imagine that the image have the istream and ostream overloading)
    why the user class needs, too, overloading the istream and ostream? if i have the overloading on members, why do i need for user too?

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

    Re: can i convert HBITMAP to istream?

    why the user class needs, too, overloading the istream and ostream? if i have the overloading on members, why do i need for user too?
    Have you tried stream insertion/extraction for type user without overloading << and >> for that type?

    The type passed to an overloaded operator (or function) needs to match a function/operator definition for that type. If you wanted to pass a type user to a function you would provide a function definition that took as a parameter a type user. Passing type user to overloaded <</>> functions is no different.
    Last edited by 2kaud; July 18th, 2016 at 04:03 PM.
    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++17 Compiler: Microsoft VS2019 (16.6.5)

  11. #11
    Join Date
    Dec 2018
    Posts
    3

    Re: can i convert HBITMAP to istream?

    How do I convert IStream to HBITMAP

  12. #12
    Join Date
    Apr 2009
    Posts
    1,298

    Re: can i convert HBITMAP to istream?

    vinay i don't know everything lol
    but maybe these code help you
    Code:
    //Using GdiPlus I got something that works pretty well and doesn't involve pulling any teeth!Gdiplus::Bitmap* pBitmap = NULL;
    IStream* pStream = NULL;
    
    HRESULT hResult =::CreateStreamOnHGlobal( NULL, TRUE,&pStream );
    if(hResult == S_OK && pStream)
    {
        hResult = pStream->Write(&bits[0], ULONG(bits.size()), NULL);
        if(hResult == S_OK)
            pBitmap =Gdiplus::Bitmap::FromStream(pStream);
        pStream->Release();}

  13. #13
    Join Date
    Dec 2018
    Posts
    3

    Re: can i convert HBITMAP to istream?

    Thanks for your reply. I tried implementing the piece of code provided by you. I'm actually trying to send cursor shape from one machine and create the cursor in another machine and then set it. But for doing it write now I'm doing a POC to check if it works. I want to send stream data and create a bitmap of mask and color for the cursor and do the rest of the thing.

    Please find the below code snippet for the same. I'm unable to create the ICON and it returns NULL. Please correct me if I'm missing anything.

    Code:
    //To Get Cursor Information
    	CURSORINFO Cursor;
    	Cursor.cbSize = sizeof(CURSORINFO);
    	GetCursorInfo(&Cursor);
    	ICONINFO iconInfo; 
    	GetIconInfo(Cursor.hCursor, &iconInfo);
    	
    	//Start of getting  Color stream
    
        CImage   img;
        IStream* pStream = NULL;
        HRESULT  hr = CreateStreamOnHGlobal(NULL, TRUE, &pStream);
    
        if (FAILED(hr))
            return FALSE;
    
    	img.Attach(iconInfo.hbmColor);
        hr = img.Save(pStream, Gdiplus::ImageFormatBMP);
        if (FAILED(hr))
        {
            pStream->Release();
            return FALSE;
        }
    	//End of getting color stream 
    
    	//Start of getting  mask stream
    	CImage   imgmask;
        IStream* pStreammask = NULL;
          hr = CreateStreamOnHGlobal(NULL, TRUE, &pStreammask);
    
        if (FAILED(hr))
            return FALSE;
    
    	imgmask.Attach(iconInfo.hbmMask);
        hr = imgmask.Save(pStreammask, Gdiplus::ImageFormatBMP);
        if (FAILED(hr))
        {
            pStreammask->Release();
            return FALSE;
        }
    	//End of getting  mask stream
    
    	//Start of creating a HBITMAP from color stream
    	HBITMAP bmpcolor = NULL;
    	BYTE bits[4096];
    	HRESULT hResult =::CreateStreamOnHGlobal( NULL, TRUE,&pStream );
    	if(hResult == S_OK && pStream)
    	{
    		hResult = pStream->Write(&bits[0], sizeof(bits), NULL);
    		if(hResult == S_OK)
    			bmpcolor = (HBITMAP)Gdiplus::Bitmap::FromStream(pStream);
    		pStream->Release();
    	}
    	//End of creating a HBITMAP from color stream
    
    	//Start of creating a HBITMAP from mask stream
    	BYTE bitsmask[4096];
    	HBITMAP bmpmask = NULL;
    	 hResult =::CreateStreamOnHGlobal( NULL, TRUE,&pStreammask );
    	if(hResult == S_OK && pStreammask)
    	{
    		hResult = pStreammask->Write(&bitsmask[0], sizeof(bitsmask), NULL);
    		if(hResult == S_OK)
    			 bmpmask = (HBITMAP)Gdiplus::Bitmap::FromStream(pStreammask);
    		pStreammask->Release();
    	}
    	//End of creating a HBITMAP from mask stream
    
    	//Creating the IconInfo
    	ICONINFO iii;
    	iii.hbmColor = bmpcolor;
    	iii.hbmMask = bmpmask;
    	iii.fIcon = FALSE;
    	iii.xHotspot = 10;
    	iii.yHotspot = 10;
    
    	HICON ii = CreateIconIndirect(&iii); //Createicon 
    	if(ii == NULL)
    		MessageBox(NULL,"Icon Not Create","Icon not Created",0);
    	
    
    	BOOL bValue = ::SetSystemCursor(ii,32512); //To check if cursor is created
    Last edited by 2kaud; December 20th, 2018 at 08:42 AM. Reason: Added code tags

  14. #14
    Join Date
    Apr 2009
    Posts
    1,298

    Re: can i convert HBITMAP to istream?

    to be honest:
    - i don't use that code some time;
    - isn't easy use IStreams.
    you can get the HICON?
    if so the problem must be on IStreams creations.... belive me these is hard to understand it, because we can't find a tutorial that helps more
    anotherthing that can help you more
    try to test line by line, function return... if you know what they return, will me more easy to find the problem and where

  15. #15
    Join Date
    Dec 2018
    Posts
    3

    Re: can i convert HBITMAP to istream?

    Thank you for your support. I will see if someone else could be of help. Because I had been struggling this for a while.

    To get the Cursor image from one machine and create it on another machine without saving it to file in any of the machines. I'm able to send data using socket programming(implementation already exists ).

    I tried using one approach but the issue was it does't support some icons. Please find the link

    So, wanted to know if there is any other way through which I can do it.

Page 1 of 2 12 LastLast

Posting Permissions

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


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)