无法使用 FreeImage 将元数据添加到 JPEG 图像

fpi*_*tte 2 delphi freeimage

我尝试将元数据添加到现有 JPEG 文件并将图像保存在另一个文件中。我正在使用 Delphi 11 和 FreeImage(Delphi 包装器)。生成的图像与现有图像相同,没有添加元数据标签。完全没有错误。

这是重现该问题的简单独立过程:

procedure AddTagArtistTest;
var
    fif      : FREE_IMAGE_FORMAT;
    dib      : PFIBITMAP;
    Tag      : PFITAG;
    TagValue : AnsiString;
    TagKey   : AnsiString;
    TagID    : WORD;
    Filename : String;
    Success  : Boolean;
begin
    Filename := 'F:\Images\ExistingImage.jpg'; // Already has metadata but no TAG_ARTIST
    dib      := nil;
    Success  := FALSE;
    try
        fif := FreeImage_GetFileTypeU(PChar(FileName), 0);
        if fif = FIF_UNKNOWN then
            fif := FreeImage_GetFIFFromFilenameU(PChar(FileName));
        if fif = FIF_UNKNOWN then
            Exit;
        if not FreeImage_FIFSupportsReading(fif) then
            Exit;
        dib    := FreeImage_LoadU(fif, PChar(Filename), 0);
        if dib = nil then
            Exit;
        Tag      := FreeImage_CreateTag();
        TagValue := 'FRANCOIS PIETTE';
        TagKey   := 'Artist';
        TagID    := $013B; // TAG_ARTIST;
        if not FreeImage_SetTagID(Tag, TagID) then
            Exit;
        if not FreeImage_SetTagKey(Tag, PAnsiChar(TagKey)) then
            Exit;
        if not FreeImage_SetTagType(Tag, FIDT_ASCII) then
            Exit;
        if not FreeImage_SetTagLength(Tag, Length(TagValue) + 1) then
            Exit;
        if not FreeImage_SetTagCount(Tag,  Length(TagValue) + 1) then
            Exit;
        if not FreeImage_SetTagValue(Tag, PAnsiChar(TagValue)) then
            Exit;
        if not FreeImage_SetMetadata(FIMD_EXIF_MAIN,
                                     dib,
                                     PAnsiChar(TagKey),
                                     Tag) then
            Exit;
        if not FreeImage_SaveU(FIF_JPEG,
                               dib,
                               PChar(ChangeFileExt(FileName, '_2.jpg')),
                               0) then
            Exit;
        Success := TRUE;
    finally
        if dib <> nil then
            FreeImage_Unload(dib);
        if Success then
            WriteLn('Success')
        else
            WriteLn('Failed');
    end;
end;
Run Code Online (Sandbox Code Playgroud)

知道我做错了什么吗?

Ami*_*ack 5

根据文档,第 76 页,表 13不支持写入EXIF_MAINa - 只能读取:JPEG

FIF_JPEG FIF_TIFF FIF_PNG FIF_GIF FIF_RAW FIF_JXR FIF_WEBP
0 = FIMD_评论 读/写 - 读/写 读/写 - - -
1 = FIMD_EXIF_MAIN 读/写 - - 读/写
2 = FIMD_EXIF_EXIF - - 读/写
3 = FIMD_EXIF_GPS - - - 读/写
4 = FIMD_EXIF_MAKERNOTE - - -
5 = FIMD_EXIF_INTEROP - - -
6 = FIMD_IPTC 读/写 读/写 - - - 读/写 -
7 = FIMD_XMP 读/写 读/写 读/写 - - 读/写 读/写
8 = FIMD_GEOTIFF - 读/写 - - - - -
9 = FIMD_动画 - - - 读/写 - - -
10 = FIMD_自定义 - - - - - - -
11 = FIMD_EXIF_RAW 读/写 - - - - - 读/写

这意味着:如果您将其另存为 ie,FIF_TIFF您将获得一张包含新设置的元数据的图片。只需将您的代码更改为:

        if not FreeImage_SaveU(FIF_TIFF,
                               dib,
                               PChar(ChangeFileExt(FileName, '_2.tif')),
                               0) then
Run Code Online (Sandbox Code Playgroud)

并且不要忘记再次释放标签:

FreeImage_DeleteTag( Tag );
Run Code Online (Sandbox Code Playgroud)

使用 FreeImage 3.18.0 和 D7 成功测试了这一点。一个反例是使用 IPTC 或 XMP 而不是 EXIF,因为它们具有对 JPEG 图片的写入支持。