Re: PropertyNotSupported returned for sample code



Here is the code that I used. I tested saving as a jpeg and png on
WindowsXPSP2. Both test cases worked without error:
// compiled with Visual Studio 2005
// cl /EHsc fakephoto.cpp

// fakephoto.cpp
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

#pragma comment( lib, "gdiplus.lib" )

static LPCSTR DebugPrint( DWORD dwError )
{
LPVOID lpMsgBuf = NULL;

::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);

if ( lpMsgBuf )
{
// Process any inserts in lpMsgBuf.
// ...
// Display the string.
::OutputDebugString((LPCTSTR)lpMsgBuf);
}

return (LPCTSTR)lpMsgBuf;
}

int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes

Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

Gdiplus::GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure

pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure

Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}

free(pImageCodecInfo);
return -1; // Failure
}

INT main()
{
// Initialize <tla rid="tla_gdiplus"/>.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Status stat;
CLSID clsid;
char propertyValue[] = "Fake Photograph";
Bitmap* bitmap = new Bitmap(L"c:\\TestImages\\FakePhoto.jpg");
PropertyItem* propertyItem = new PropertyItem;
// Get the CLSID of the JPEG encoder.
GetEncoderClsid(L"image/png", &clsid);
propertyItem->id = PropertyTagImageTitle;
propertyItem->length = lstrlen(propertyValue) + 1; // string length
including NULL terminator
propertyItem->type = PropertyTagTypeASCII;
propertyItem->value = propertyValue;
bitmap->SetPropertyItem(propertyItem);
stat = bitmap->Save(L"c:\\TestImages\\FakePhoto2.jpg", &clsid, NULL);

LPCSTR lpMsgBuf = DebugPrint(bitmap->GetLastStatus());
if(stat == Ok)
printf("FakePhoto2.jpg saved successfully.\n");
else
printf("Error: %s\n", lpMsgBuf);

LocalFree((HLOCAL)lpMsgBuf);

delete propertyItem;
delete bitmap;
GdiplusShutdown(gdiplusToken);
return 0;
}

Additionally, I used the IStoragePropertySet API exposed by the shell to
read back the property values for both images.

For both the jpeg and png, the PropertyTagImageTitle was "Fake Photograph".


"seanick" <seanick@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:eapOO6elGHA.676@xxxxxxxxxxxxxxxxxxxxxxx
Hi Michael,
Thanks for the reply.
Unfortunately, I wasn't even using that code... I only had the sample code
which had the length for that string hard coded:
char szPropertyValue[] = "Fake Photograph";
pItem->length = 16;
pItem->value = szPropertyValue;

Which was not working for me. Just in case, though, I tried your
suggestion, and changed that line to the following:

pItem->length = (ULONG) strlen(propertyValue) +1;

It still fails with - PropertyNotSupported -. I wonder why this is not
working on my system. Did you try it on a 2003 server or windows XP sp2?
Does the version of the GDIPLUS assembly make a difference, or the fact
that I am building it debug for the time being?
my input lib's, just in case for whatever reason it matters, are these,
(plus the defaults in VS2005 TS) ScrnSavW.Lib MSImg32.Lib shlwapi.lib
comctl32.lib gdiplus.lib
Any ideas what to try to make this API work? Could you send me an example
of a jpg or something that had these properties set by the sample code? I
can't seem to notice any change to the jpg between calling that code, or
not.

Thanks!
NICK

------------

"Michael Phillips, Jr." <mphillips53@xxxxxxxxxxxxxxx> wrote in message
news:eBf5ZKJlGHA.1264@xxxxxxxxxxxxxxxxxxxxxxx
Microsoft's sample works fine for jpeg and png files.

pItem->length = strlen(szPropertyValue);

This line should read:
// must include null character
pItem->length = strlen(szPropertyValue) + 1;



"seanick" <seanick@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:uDMUcDukGHA.4816@xxxxxxxxxxxxxxxxxxxxxxx
Hi, I am trying to save some metadata with a jpeg image I created (a
fractal render) and it is failing to store the data. I actually want to
use PNG instead of jpeg but it didn't work either, so I thought I would
play it safe and use the exact sample code but that didn't even work.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/usingGDIPlus/usingimagesbitmapsandmetafiles/readingandwritingmetadata.asp
the file is created but no metadata is saved. the call to the
SetPropertyItem function fails with PropertyNotSupported
however the code looks just like the sample. What would cause this
failure?

Also, will it support unicode if I am using unicode everywhere else? or
does it have to be ansi?

thanks
NICK

// save the jpg file

Status stat;

PropertyItem* pItem = new PropertyItem();

pItem->id = PropertyTagImageTitle;

pItem->type = PropertyTagTypeASCII;

char szPropertyValue[] = "Fake Photograph"; // actually going to be
something else, but just to ensure the sample code failed too, I used
the same value..

// end result is going to look more like

//char szPropertyValue[MAX_PATH];

//StringCchPrintFA(szPropertyValue, MAX_PATH, "real,imag,pixel =
%f,%f,%f", fractal.fReal, fractal.fImag,fractal.fPixel);

//etc.

pItem->length = 16;

// which will instead be

// pItem->length = strlen(szPropertyValue);

pItem->value = szPropertyValue;

if ( PropertyNotSupported == image->SetPropertyItem(pItem) )

{

DebugString( _T("CompressBmpToPng: SetPropertyItem failed to set
PropertyTagImageTitle!\n") );

}

stat = image->Save( pwszPngFileName, &encoderClsid, NULL);









.



Relevant Pages

  • Re: PropertyNotSupported returned for sample code
    ... I have no problems setting or viewing the properties for jpeg, ... GdiplusStartupInput gdiplusStartupInput; ... PropertyItem* propertyItem = new PropertyItem; ... would play it safe and use the exact sample code but that didn't even ...
    (microsoft.public.win32.programmer.gdi)
  • Re: PropertyNotSupported returned for sample code
    ... GdiplusStartupInput gdiplusStartupInput; ... PropertyItem* propertyItem = new PropertyItem; ... SetPropertyItem function fails with PropertyNotSupported ...
    (microsoft.public.win32.programmer.gdi)
  • Re: C++ GDI+ Example to VB (Pointer Conversion Problem)
    ... propertyItem is very probably a pointer to an object. ... // Initialize GDI+. ... GdiplusStartupInput gdiplusStartupInput; ... CLSID clsid; ...
    (microsoft.public.vb.winapi)