Andy Bantly Ответов: 1

Этот код должен работать, но он не работает


Этот пример кода ниже демонстрирует использование CImage (от ATLImage. h) для загрузки файла на основе изображения, сохранения его в потоке и создания интерфейса COM-изображения, который может быть возвращаемым значением в свойстве Ole automation.

Самое сумасшедшее, что OleLoadPicture терпит неудачу с кодом ошибки, указывающим на поврежденный формат файла. Тем не менее, я могу продемонстрировать в состоянии ошибки, что поток может быть снова загружен во второй CImage и сохранен обратно на диск. Сравнение двух растровых изображений на основе файлов показывает, что они идентичны.

Это запутанная проблема, так как это кажется лучшим способом передачи данных изображения в COM.

Кто-нибудь может подумать, почему это не удается? Мое единственное подозрение заключается в том, что сохраненный BMP каким-то образом не соответствует какому-то стандарту, но опять же я могу посмотреть на него с помощью любого средства просмотра изображений

///////////////////////////////////////////////////////////////
// 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();
		}
	}
}

Matthew Faithfull

Похоже, это должно сработать. Пробовали ли вы поиграть с опциями OleLoadPicture, например

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

Чтобы он мог определить, сколько данных нужно получить, и не пытаться сохранить исходный формат.

Andy Bantly

Вы знаете, я не пытался перейти от ложного к истинному, чтобы позволить ему преобразовать изображение. Я действительно попробовал значение 0, но получил тот же результат. Это так смущает меня. Я могу пройти через эти вращения, чтобы сохранить файл на диск, а затем использовать мое альтернативное решение НИЖЕ, чтобы загрузить его в IPictureDisp. Единственное, что я мог придумать, - это каким-то образом создать CStreamArchive из IStream. Это должно быть возможно, так как IStream является базовым классом CStreamArchives. Вероятно, мне следует попытаться просмотреть данные для обоих случаев в памяти и посмотреть, есть ли что-то явно отличающееся в потоках. например, один из них хранит Юникод, а другой-необработанные байтовые данные.

Matthew Faithfull

К сожалению, я не могу предложить больше в виде предложений. Я почти ничего не делал с Истримом, кроме как распределял вещи между квартирами нитей, и это было достаточно кошмарно. По крайней мере, тебе есть что попробовать. Поскольку у вас есть хороший законсервированный пример, вы можете даже получить некоторую радость от поддержки Microsoft, учитывая, что вы получаете ошибку, не указанную в документации MSDN, от API, для которого ваши параметры кажутся допустимыми.

1 Ответов

Рейтинг:
4

Andy Bantly

Я наконец-то решил эту проблему (давным-давно) и теперь обновляю вопрос. Проблема заключалась в том, что поток должен быть перемотан до OleLoadPicture. Код, который я добавил, чтобы исправить это и заставить его работать, был:

 // Rewind the stream for picture loading
LARGE_INTEGER li;
li.QuadPart  = 0;
pImageStream->Seek(li,STREAM_SEEK_SET,NULL);


Patrice T

С тем же успехом вы можете принять свой ответ.