Thread: GDIPLUS::Image: how save it on a file in stream way?

  1. #31
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    i did the changes:
    Code:
    friend std::ostream& operator << (std::ostream& lhs, const image& rhs)
        {
    
            //Create an empty IStream:
            IStream* pIStream = nullptr;
            if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
            //choose image format for save it on IStream:
            // Get encoder class id for jpg compression
            // for other compressions use
            //    image/bmp
            //    image/jpeg
            //    image/gif
            //    image/tiff
            //    image/png
            CLSID pngClsid;
            GetEncoderClsid(L"image/gif", &pngClsid);
    
            // Setup encoder parameters
            EncoderParameters encoderParameters;
            encoderParameters.Count = 1;
            encoderParameters.Parameter[0].Guid = EncoderQuality;
            encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
            encoderParameters.Parameter[0].NumberOfValues = 1;
    
            // setup compression level
            ULONG quality = 50;
            encoderParameters.Parameter[0].Value = &quality;
    
            //  Save the image to the stream
    
            if(rhs.img->Save(pIStream, &pngClsid, &encoderParameters) != Ok)
            {
                pIStream->Release();
                DebugText("error on saving to IStream");
            }
    
            //getting the stream size:
    
            HGLOBAL hg;
            GetHGlobalFromStream(pIStream,&hg);
            int buffsize=GlobalSize(hg);
            if(buffsize==0)
                DebugText("error on getting IStream size");
            char *pBuff = new char[buffsize];
            ULONG ulBytesRead;
    
            //Read the stream to pBuff
            if(pIStream->Read(pBuff,buffsize, &ulBytesRead)!=S_OK)
                DebugText("error on saving IStream to buffer");
    
            //write the stream size on file
            lhs.write(reinterpret_cast<char*>(&buffsize),sizeof(buffsize));
    
            //write pBuff data on file
            lhs.write(reinterpret_cast<char*>(&pBuff),sizeof(pBuff));
    
            //clean resources
            delete[] pBuff;
            pIStream->Release();
    
            return lhs;
        }
    
        friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            IStream* pIStream = nullptr;
    
            // Create stream with 0 size
            HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,0);
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),sizeof(streamsize));
            GlobalUnlock(hg);
    
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
            //reading IStream on Image class:
            if(rhs.img->FromStream(pIStream,TRUE)!=S_OK)
                DebugText("error reading stream to Image");
    
            //realease resources:
            pIStream->Release();
            GlobalFree(hg);
            return lhs;
        }
    but i continue with a memory leak on read

  2. #32
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Line 57: How many bytes do you want to write? (hint: it's not 4)
    Line 74: Why would you do that?
    Line 88: Remove.

    gg

  3. #33
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Codeplug View Post
    Line 57: How many bytes do you want to write? (hint: it's not 4)
    Line 74: Why would you do that?
    Line 88: Remove.

    gg
    i did that changes:
    Code:
    friend std::ostream& operator << (std::ostream& lhs, const image& rhs)
        {
    
            //Create an empty IStream:
            IStream* pIStream = nullptr;
            if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
            //choose image format for save it on IStream:
            // Get encoder class id for jpg compression
            // for other compressions use
            //    image/bmp
            //    image/jpeg
            //    image/gif
            //    image/tiff
            //    image/png
            CLSID pngClsid;
            GetEncoderClsid(L"image/gif", &pngClsid);
    
            // Setup encoder parameters
            EncoderParameters encoderParameters;
            encoderParameters.Count = 1;
            encoderParameters.Parameter[0].Guid = EncoderQuality;
            encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
            encoderParameters.Parameter[0].NumberOfValues = 1;
    
            // setup compression level
            ULONG quality = 50;
            encoderParameters.Parameter[0].Value = &quality;
    
            //  Save the image to the stream
    
            if(rhs.img->Save(pIStream, &pngClsid, &encoderParameters) != Ok)
            {
                pIStream->Release();
                DebugText("error on saving to IStream");
            }
    
            //getting the stream size:
    
            HGLOBAL hg;
            GetHGlobalFromStream(pIStream,&hg);
            int buffsize=GlobalSize(hg);
            if(buffsize==0)
                DebugText("error on getting IStream size");
            char *pBuff = new char[buffsize];
            ULONG ulBytesRead;
    
            //Read the stream to pBuff
            if(pIStream->Read(pBuff,buffsize, &ulBytesRead)!=S_OK)
                DebugText("error on saving IStream to buffer");
    
            //write the stream size on file
            lhs.write(reinterpret_cast<char*>(&buffsize),sizeof(buffsize));
    
            //write pBuff data on file
            lhs.write(reinterpret_cast<char*>(&pBuff),buffsize);
    
            //clean resources
            delete[] pBuff;
            pIStream->Release();
    
            return lhs;
        }
    
        friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            IStream* pIStream = nullptr;
    
            // Create stream with 0 size
            HGLOBAL hg;
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),sizeof(streamsize));
            GlobalUnlock(hg);
    
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
            //reading IStream on Image class:
            if(rhs.img->FromStream(pIStream,TRUE)!=S_OK)
                DebugText("error reading stream to Image");
    
            //realease resources:
            pIStream->Release();
            return lhs;
        }
    but the memory leak stills there.
    normaly a memory leak happens when we are moving or forbidden memory. so unless i miss the size of IStream or i don't know

  4. #34
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Line 74: Again, why would create an hg of size 0 when you need one of size 'streamsize'? (hint: that's your second parameter of GlobalAlloc).
    Line 77: You just read "sizeof(streamsize)" bytes from the stream. You want 'streamsize' bytes.

    gg

  5. #35
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Codeplug View Post
    Line 74: Again, why would create an hg of size 0 when you need one of size 'streamsize'? (hint: that's your second parameter of GlobalAlloc).
    Line 77: You just read "sizeof(streamsize)" bytes from the stream. You want 'streamsize' bytes.

    gg
    thanks for that.
    Code:
    friend std::ostream& operator << (std::ostream& lhs, const image& rhs)
        {
    
            //Create an empty IStream:
            IStream* pIStream = nullptr;
            if(CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
            //choose image format for save it on IStream:
            // Get encoder class id for jpg compression
            // for other compressions use
            //    image/bmp
            //    image/jpeg
            //    image/gif
            //    image/tiff
            //    image/png
            CLSID pngClsid;
            GetEncoderClsid(L"image/gif", &pngClsid);
    
            // Setup encoder parameters
            EncoderParameters encoderParameters;
            encoderParameters.Count = 1;
            encoderParameters.Parameter[0].Guid = EncoderQuality;
            encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
            encoderParameters.Parameter[0].NumberOfValues = 1;
    
            // setup compression level
            ULONG quality = 50;
            encoderParameters.Parameter[0].Value = &quality;
    
            //  Save the image to the stream
    
            if(rhs.img->Save(pIStream, &pngClsid, &encoderParameters) != Ok)
            {
                pIStream->Release();
                DebugText("error on saving to IStream");
            }
    
            //getting the stream size:
    
            HGLOBAL hg;
            GetHGlobalFromStream(pIStream,&hg);
            int buffsize=GlobalSize(hg);
            if(buffsize==0)
                DebugText("error on getting IStream size");
            char *pBuff = new char[buffsize];
            ULONG ulBytesRead;
    
            //Read the stream to pBuff
            if(pIStream->Read(pBuff,buffsize, &ulBytesRead)!=S_OK)
                DebugText("error on saving IStream to buffer");
    
            //write the stream size on file
            lhs.write(reinterpret_cast<char*>(&buffsize),sizeof(buffsize));
    
            //write pBuff data on file
            lhs.write(reinterpret_cast<char*>(&pBuff),buffsize);
    
            //clean resources
            delete[] pBuff;
            pIStream->Release();
    
            return lhs;
        }
    
        friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            // getting IStream data:
            IStream* pIStream = nullptr;
            HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,streamsize);
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),streamsize);
            GlobalUnlock(hg);
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
            //reading IStream on Image class:
            if(rhs.img->FromStream(pIStream,TRUE)!=S_OK)
                DebugText("error reading stream to Image");
            else
                DebugText("reading stream to Image sucessfull");
    
            //realease resources:
            pIStream->Release();
            GlobalFree(hg);
            return lhs;
        }
    now i don't get memory leak but the IStream isn't read to image

  6. #36
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Line 89: Remove.

    Line 82: https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
    FromStream() is static and returns an Image*.

    gg

  7. #37
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Code:
    friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            // getting IStream data:
            IStream* pIStream = nullptr;
            HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,streamsize);
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),streamsize);
            GlobalUnlock(hg);
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
            //reading IStream to Image class:
            rhs.img=Image::FromStream(pIStream);
            Status stat = rhs.img->GetLastStatus();
            if(stat!=S_OK)
                DebugText("error reading stream to Image");
            else
                DebugText("reading stream to Image sucessfull");
    
            //realease resources:
            pIStream->Release();
            return lhs;
        }
    thanks for all, but i continue getting that error message

  8. #38

  9. #39
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Codeplug View Post
    What is the value of stat?
    it's 2. is these:
    STG_E_ACCESSDENIED: The caller does not have enough permissions for accessing statistics for this storage object.
    ???

  10. #40
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    https://msdn.microsoft.com/en-us/library/ms886955.aspx
    >> If the logical size of the stream is important, you should follow the call to this function with a call to the IStream::SetSize method.
    Try that.

    gg

  11. #41
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Codeplug
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    https://msdn.microsoft.com/en-us/library/ms886955.aspx
    >> If the logical size of the stream is important, you should follow the call to this function with a call to the IStream::SetSize method.
    Try that.

    gg
    i'm sorry, but i miss something:
    Code:
    friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            // getting IStream data:
            IStream* pIStream = nullptr;
            HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,streamsize);
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),streamsize);
            GlobalUnlock(hg);
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
            
            //change the IStream size:
            STATSTG statstg;
            memset (&statstg, 0, sizeof(statstg));
            pIStream->Stat(&statstg, STATFLAG_NONAME);
            pIStream->SetSize(statstg.cbSize);
    
            //reading IStream to Image class:
            rhs.img=Image::FromStream(pIStream);
            Status stat = rhs.img->GetLastStatus();
            if(stat!=S_OK)
                DebugText("error reading stream to Image: "  + to_string(stat));
            else
            {
                DebugText("reading stream to Image sucessfull");
            }
    
    
            //realease resources:
            pIStream->Release();
            return lhs;
        }
    maybe i miss something, because, from CreateStreamOnHGlobal(), i only have hg

  12. #42
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Remove 16-20 and replace with pIStream->SetSize(streamsize). See if that works.

    gg

  13. #43
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Codeplug View Post
    Remove 16-20 and replace with pIStream->SetSize(streamsize). See if that works.

    gg
    error: "no matching function for call to 'IStream::SetSize(int&)'"
    candidate: "virtual HRESULT IStream::SetSize(ULARGE_INTEGER)"

  14. #44
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    What you want to do that point is get on MSDN and lookup "ULARGE_INTEGER".
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    Code:
        ULARGE_INTEGER li;
        li.QuadPart = (ULONGLONG)streamsize;
    gg

  15. #45
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Codeplug View Post
    What you want to do that point is get on MSDN and lookup "ULARGE_INTEGER".
    https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

    Code:
        ULARGE_INTEGER li;
        li.QuadPart = (ULONGLONG)streamsize;
    gg
    i did, but the error message is showed. so the image isn't readed.
    Code:
    friend std::istream& operator >> (std::istream& lhs, image& rhs)
        {
            //getting IStream size:
            int streamsize;
            lhs.read(reinterpret_cast<char*>(&streamsize), sizeof(streamsize));
    
            // getting IStream data:
            IStream* pIStream = nullptr;
            HGLOBAL hg= ::GlobalAlloc(GMEM_MOVEABLE,streamsize);
            void* p =GlobalLock(hg);
            lhs.read(reinterpret_cast<char*>(p),streamsize);
            GlobalUnlock(hg);
            
            if(CreateStreamOnHGlobal(hg, TRUE, (LPSTREAM*)&pIStream)!=S_OK)
                DebugText("error on creating an empty IStream");
    
    
            ULARGE_INTEGER li;
            li.QuadPart = (ULONGLONG)streamsize;
            pIStream->SetSize(li);
            //reading IStream to Image class:
            rhs.img=Image::FromStream(pIStream);
            Status stat = rhs.img->GetLastStatus();
            if(stat!=S_OK)
                DebugText("error reading stream to Image: "  + to_string(stat));
            else
            {
                DebugText("reading stream to Image sucessfull");
            }
    
    
            //realease resources:
            pIStream->Release();
            return lhs;
        }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Displaying Image from stream
    By NetCoder in forum C++ Programming
    Replies: 5
    Last Post: 02-25-2013, 03:04 AM
  2. How can I save an image to file.
    By vmars316 in forum Windows Programming
    Replies: 1
    Last Post: 12-26-2010, 09:44 AM
  3. Low level program to save a mjpeg stream
    By Rufe0 in forum Linux Programming
    Replies: 6
    Last Post: 09-22-2009, 05:53 AM
  4. how to save one svg image by programing
    By sfguofen in forum C++ Programming
    Replies: 9
    Last Post: 09-04-2009, 08:11 PM
  5. How to get image from the screen and then save it to a file?
    By nomer in forum Windows Programming
    Replies: 2
    Last Post: 05-25-2006, 08:46 AM