Click here to Skip to main content
11,920,772 members (61,381 online)
Rate this:
Please Sign up or sign in to vote.
See more: C++
This sample code below demonstrates using CImage (from ATLImage.h) to load a file based image, save it to a stream, and create a COM picture interface which can be the return value in an OLE automation property.

The crazy thing is that OleLoadPicture fails with an error code indicating a corrupted file format. However, I am able to demonstrate in the error condition that the stream can again be loaded in a second CImage and saved back to disk. Comparison of the two file based bitmaps shows them to be identical.

It is a confounding problem as this seems the best way to pass image data around in COM.

Can anyone think of why this fails? My only suspicion is that the saved BMP somehow does not conform to some standard but then again I can look at it with any image viewer

// OLE Stream file necessary for OleLoadPicture support
COleStreamFile ImageStream;
// Prepare the Image for memory stream serialization
if (ImageStream.CreateMemoryStream())
	// GDI+ Image support
	CImage ImageDIB;
	// Attach the DIB to the Image
	if (SUCCEEDED(ImageDIB.Load(L"C:\\Users\\abantly\\AppData\\Local\\Temp\\Image.bmp")))
		// Serialize to the memory stream the DIB to the BMP format
		IStream * pImageStream = ImageStream.GetStream();
		if (pImageStream && SUCCEEDED(ImageDIB.Save(pImageStream,Gdiplus::ImageFormatBMP)))
			CComPtr<IPicture> Picture;
			HRESULT hr = OleLoadPicture(pImageStream,(LONG)ImageStream.GetLength(),FALSE,IID_IPicture,(LPVOID *)&Picture);
			if (SUCCEEDED(hr))
				// FAILS TO GET HERE with code -2146827807
				CComQIPtr<IPictureDisp> PictureDisp(Picture);
				CImage ImageDIB2;
				if (SUCCEEDED(ImageDIB2.Load(pImageStream)))
			// Release the stream
Posted 10-Apr-13 18:11pm
Matthew Faithfull 11-Apr-13 5:33am
Does seem like it should work. Have you tried playing around with the OleLoadPicture options e.g.

HRESULT hr = OleLoadPicture(pImageStream, 0, TRUE, IID_IPicture,(LPVOID *)&Picture);

To let it work out how much data to get and to not attempt to keep the original format.
Andy Bantly 11-Apr-13 18:08pm
You know, I didn't try changing from FALSE to TRUE to let it convert the image. I did try the 0 value but got the same result. It is so confounding to me. I can go through those gyrations to save the file to disk and then use my alternate solution below to load it into a IPictureDisp. The only other thing I could think to do is to somehow create a CStreamArchive from a IStream. It should be possible since IStream is CStreamArchives base class. I should probably try to look at the data for both cases in memory and see if there is anything obviously different about the streams. e.g. one is store unicode and the other as raw byte data.
Matthew Faithfull 11-Apr-13 18:18pm
Sorry I can't offer more in the way of suggestions. I've not done much with IStream except for marshalling stuff between thread apartments and that was nightmarish enough. At least you have some things to try. As you have a nice canned example you might even get some joy from Microsoft support given that you're getting an error not listed in the MSDN documentation from an API for which your parameters appear to be valid.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 548
1 Dave Kreskowiak 245
2 phil.o 170
3 KrunalRohit 134
4 F-ES Sitecore 130
0 OriginalGriff 6,778
1 KrunalRohit 4,530
2 Sergey Alexandrovich Kryukov 3,203
3 George Jonsson 2,815
4 Suvendu Shekhar Giri 2,181

Advertise | Privacy | Mobile
Web02 | 2.8.151120.1 | Last Updated 10 Apr 2013
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100