I try to add metadata to an existing JPEG file and saving the image in another file. I'm using Delphi 11 and FreeImage (Delphi wrapper). The image is produced identical to the existing image, without the added metadata tag. No error at all.
Here is a simple stand alone procedure to reproduce the issue:
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;
Any idea about what I'm doing wrong?
CodePudding user response:
As per the documentation, page 76, Table 13 writing EXIF_MAIN
to a JPEG
is not supported - only reading is:
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 |
Which means: if you save it as i.e. FIF_TIFF
you'll get a picture with your newly set metadata in it. Simply change your code into:
if not FreeImage_SaveU(FIF_TIFF,
dib,
PChar(ChangeFileExt(FileName, '_2.tif')),
0) then
And don't forget to free the tag again:
FreeImage_DeleteTag( Tag );
Successfully tested this with FreeImage 3.18.0 and D7. A counter example would be to use IPTC or XMP instead of EXIF, as those have write support for a JPEG picture.