GDI+ Image::SetPropertyItem 未按预期工作

GDI+ Image::SetPropertyItem not working as expected

我正在尝试使用 SetPropertyItem 将拍摄日期 属性 设置到文件 (click here for MSDN docs description)。

我尝试将新初始化的 FILETIME 分配给输入图像,但没有成功(或错误消息)。为了确保这不是拍摄日期的问题,我也尝试了 this MSDN example 无济于事。

目前,我正在尝试从一个输入文件中提取拍摄日期 属性 项目(工作正常)并尝试将其设置到另一个文件。这种做法也不行,返回的Status码一直是0(Ok)。

我使用的代码如下。我只能假设我犯了一个简单的错误,或者可能误解了 SetPropertyItem 应该做什么。我认为 SetPropertyItem 更改了元数据值,以便可以通过 Windows 属性菜单查看它,如 this screenshot.

#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
#include <iostream>
using namespace Gdiplus;

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

int main()
{
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    Image* image = new Image(L"FakePhoto.jpg"); // input image

    UINT totalBufferSize;
    UINT numProperties; // setup the buffer
    image->GetPropertySize(&totalBufferSize, &numProperties);

   // extract all metadata property items
   PropertyItem* pAllItems = (PropertyItem*)malloc(totalBufferSize);
   image->GetAllPropertyItems(totalBufferSize, numProperties, pAllItems);

   for (UINT j = 0; j < numProperties; ++j)
   { // loop through each property
       if (pAllItems[j].id == PropertyTagExifDTOrig)
       { // if it's the Date Taken property
            PropertyItem* propItem = new PropertyItem;
            Image* newImage = new Image(L"Test2.jpg");
            Status status; // second image

            propItem->id = PropertyTagExifDTOrig;
            propItem->length = pAllItems[j].length;
            propItem->type = PropertyTagTypeASCII;
            propItem->value = pAllItems[j].value;
            // create a new property item with the input photo Date Taken metadata
            status = newImage->SetPropertyItem(propItem);

            if (status == Ok)
                std::cout << "No errors.";
        }
    }

    free(pAllItems);
    delete image;
    GdiplusShutdown(gdiplusToken);
}

非常感谢任何帮助。另外,对于任何 obvious/potential 错误,我深表歉意。我仍在学习中,因为这是我第一次使用 C++。

您的代码工作正常,但您必须将图像保存回来,例如这样

...
newImage->SetPropertyItem(propItem);

CLSID clsid;
GetEncoderClsid(L"image/jpeg", &clsid);
newImage->Save(L"Test2.jpg", &clsid);
...

BOOL GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT num = 0;
    UINT size = 0;
    ImageCodecInfo* info = NULL;

    ZeroMemory(pClsid, sizeof(CLSID));
    GetImageEncodersSize(&num, &size);
    if (size == 0)
        return FALSE;

    info = (ImageCodecInfo*)(malloc(size));
    if (info == NULL)
        return FALSE;

    GetImageEncoders(num, size, info);
    for (UINT j = 0; j < num; ++j)
    {
        if (!wcscmp(info[j].MimeType, format))
        {
            *pClsid = info[j].Clsid;
            free(info);
            return TRUE;
        }
    }

    free(info);
    return FALSE;
}