无法使用 FreeImage 将元数据添加到 JPEG 图像
Can't add a metadata to a JPEG image using 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 := 3B; // 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;
知道我做错了什么吗?
根据 the documentation, page 76, Table 13 不支持将 EXIF_MAIN
写入 JPEG
- 只支持读取:
FIF_JPEG
FIF_TIFF
FIF_PNG
FIF_GIF
FIF_RAW
FIF_JXR
FIF_WEBP
0 = FIMD_COMMENTS
R/W
-
R/W
R/W
-
-
-
1 = FIMD_EXIF_MAIN
R
R/W
-
-
R
R/W
R
2 = FIMD_EXIF_EXIF
R
R
-
-
R
R/W
R
3 = FIMD_EXIF_GPS
R
-
-
-
R
R/W
R
4 = FIMD_EXIF_MAKERNOTE
R
-
-
-
R
R
R
5 = FIMD_EXIF_INTEROP
R
-
-
-
R
R
R
6 = FIMD_IPTC
R/W
R/W
-
-
-
R/W
-
7 = FIMD_XMP
R/W
R/W
R/W
-
-
R/W
R/W
8 = FIMD_GEOTIFF
-
R/W
-
-
-
-
-
9 = FIMD_ANIMATION
-
-
-
R/W
-
-
-
10 = FIMD_CUSTOM
-
-
-
-
-
-
-
11 = FIMD_EXIF_RAW
R/W
-
-
-
-
-
R/W
这意味着:如果您将其另存为 FIF_TIFF
,您将获得一张包含新设置的元数据的图片。只需将您的代码更改为:
if not FreeImage_SaveU(FIF_TIFF,
dib,
PChar(ChangeFileExt(FileName, '_2.tif')),
0) then
别忘了再次释放标签:
FreeImage_DeleteTag( Tag );
已使用 FreeImage 3.18.0 和 D7 成功测试。一个反例是使用 IPTC 或 XMP 而不是 EXIF,因为它们具有对 JPEG 图片的写入支持。
我尝试将元数据添加到现有的 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 := 3B; // 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;
知道我做错了什么吗?
根据 the documentation, page 76, Table 13 不支持将 EXIF_MAIN
写入 JPEG
- 只支持读取:
FIF_JPEG | FIF_TIFF | FIF_PNG | FIF_GIF | FIF_RAW | FIF_JXR | FIF_WEBP | |
---|---|---|---|---|---|---|---|
0 = FIMD_COMMENTS | R/W | - | R/W | R/W | - | - | - |
1 = FIMD_EXIF_MAIN | R | R/W | - | - | R | R/W | R |
2 = FIMD_EXIF_EXIF | R | R | - | - | R | R/W | R |
3 = FIMD_EXIF_GPS | R | - | - | - | R | R/W | R |
4 = FIMD_EXIF_MAKERNOTE | R | - | - | - | R | R | R |
5 = FIMD_EXIF_INTEROP | R | - | - | - | R | R | R |
6 = FIMD_IPTC | R/W | R/W | - | - | - | R/W | - |
7 = FIMD_XMP | R/W | R/W | R/W | - | - | R/W | R/W |
8 = FIMD_GEOTIFF | - | R/W | - | - | - | - | - |
9 = FIMD_ANIMATION | - | - | - | R/W | - | - | - |
10 = FIMD_CUSTOM | - | - | - | - | - | - | - |
11 = FIMD_EXIF_RAW | R/W | - | - | - | - | - | R/W |
这意味着:如果您将其另存为 FIF_TIFF
,您将获得一张包含新设置的元数据的图片。只需将您的代码更改为:
if not FreeImage_SaveU(FIF_TIFF,
dib,
PChar(ChangeFileExt(FileName, '_2.tif')),
0) then
别忘了再次释放标签:
FreeImage_DeleteTag( Tag );
已使用 FreeImage 3.18.0 和 D7 成功测试。一个反例是使用 IPTC 或 XMP 而不是 EXIF,因为它们具有对 JPEG 图片的写入支持。