Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ OleLoadPicture
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);
			}
			else
			{
				CImage ImageDIB2;
				if (SUCCEEDED(ImageDIB2.Load(pImageStream)))
					ImageDIB2.Save(L"C:\\Users\\abantly\\AppData\\Local\\Temp\\Image2.bmp");
			}
 
			// Release the stream
			pImageStream->Release();
		}
	}
}
Posted 10-Apr-13 18:11pm
Comments
Matthew Faithfull at 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 at 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 at 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 Sergey Alexandrovich Kryukov 295
1 OriginalGriff 274
2 Shweta N Mishra 216
3 PIEBALDconsult 184
4 CPallini 155
0 OriginalGriff 7,630
1 Sergey Alexandrovich Kryukov 7,022
2 DamithSL 5,586
3 Manas Bhardwaj 4,946
4 Maciej Los 4,525


Advertise | Privacy | Mobile
Web04 | 2.8.1411023.1 | Last Updated 10 Apr 2013
Copyright © CodeProject, 1999-2014
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