Exif example for C++ Builder

This example does the following:

1.

Read all of the comments in an existing Exif file, updating the Comment array.

2.

Loads and modifies the file's image.

3.

Updates some of the comments in the comment array.

4.

Saves the file.

5.

Reads and displays the updated comments.

 

Note:

Comments for GIF, TIFF, and DICOM files are simpler than the ones in this Exif example. With those file types, all of the comments are strings that you can get and set with simple assignments.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString MyCommentText; /* String for CMNT_USERCOMMENT */
int MyCommentSize; /* Size of the comment array */
AnsiString NewCommentText; /* String for CMNT_USERCOMMENT that we read */
AnsiString TmpString; /* For parsing the comment string into bytes */
AnsiString FilePath, DistanceString, ThisDate, MyMsg; /*Miscellaneous */
int ArraySize; /* Array measurements */
int i; /* Counter */
 LEADRasterIO* pMyRasterIO= NULL;
LEADRasterProcess* pMyRasterProcess= NULL;
 LEADRasterVariant* pRasterVarEmpty= NULL;
 LEADRasterVariant* pRasterVar1= NULL;
 LEADRasterVariant* pRasterVar2= NULL;
 LEADRasterVariant* pRasterVar3= NULL;

 CoCreateInstance(CLSID_LEADRasterIO, NULL, CLSCTX_ALL, IID_ILEADRasterIO, (void**)&pMyRasterIO);
 CoCreateInstance(CLSID_LEADRasterProcess, NULL, CLSCTX_ALL, IID_ILEADRasterProcess, (void**)&pMyRasterProcess);

CoCreateInstance( CLSID_LEADRasterVariant, NULL, CLSCTX_ALL, IID_ILEADRasterVariant,(void**)&pRasterVarEmpty);
CoCreateInstance( CLSID_LEADRasterVariant, NULL, CLSCTX_ALL, IID_ILEADRasterVariant,(void**)&pRasterVar1);
CoCreateInstance( CLSID_LEADRasterVariant, NULL, CLSCTX_ALL, IID_ILEADRasterVariant,(void**)&pRasterVar2);
CoCreateInstance( CLSID_LEADRasterVariant, NULL, CLSCTX_ALL, IID_ILEADRasterVariant,(void**)&pRasterVar3);

//Specify the file that we will update.
FilePath = "c:\\exif1.tif";
//Get all of the current comments from an Exif file.
//Temporarily disable method errors so that we do not fail when comments are missing->
pMyRasterIO->EnableMethodErrors = false;
for (i = 1; i <=CMNT_LAST; i++)
{
pMyRasterIO->set_Comment((short)i, pRasterVarEmpty);
pMyRasterIO->set_Comment((short)i, pMyRasterIO->ReadComment(LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), 0, (short)i));
}
pMyRasterIO->EnableMethodErrors= True;
//Load and modify the image
pMyRasterIO->Load(LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), 0, 0, 1);
pMyRasterProcess->Reverse(LEADRasterView1->Raster);

 /* Update the date when the file is generated */
 ThisDate= FormatDateTime("yyyy:mm:dd hh:nn:ss", Now());
 pRasterVar1->set_Type( VALUE_STRING );
 pRasterVar1->StringValue= (wchar_t*)ThisDate.c_str();

pMyRasterIO->set_Comment(CMNT_SZDATETIMEDIGITIZED, pRasterVar1);
pMyRasterIO->set_Comment(CMNT_SZSUBSECTIMEDIGITIZED, pRasterVarEmpty);
//Change the subject distance to 4 1/3 meters
 pRasterVar2->set_Type ( VALUE_ARRAY_LONG );
 pRasterVar2->ItemCount= 2;
 pRasterVar2->set_LongItemValue(0, 13);
 pRasterVar2->set_LongItemValue(1, 3);

pMyRasterIO->set_Comment (CMNT_SUBJECTDISTANCE, pRasterVar2);
//Specify the user comment string
MyCommentText = "This is my new comment.";
MyCommentSize = 8 + StrLen(MyCommentText.c_str());

//Define the array for the user comment.
 pRasterVar3->set_Type ( VALUE_ARRAY_BYTE );
 pRasterVar3->ItemCount= MyCommentSize;

//Fill in the ASCII prefix.
 pRasterVar3->set_ShortItemValue(0, 'A');
 pRasterVar3->set_ShortItemValue(1, 'S');
 pRasterVar3->set_ShortItemValue(2, 'C');
 pRasterVar3->set_ShortItemValue(3, 'I');
 pRasterVar3->set_ShortItemValue(4, 'I');
 pRasterVar3->set_ShortItemValue(5, 0);
 pRasterVar3->set_ShortItemValue(6, 0);
 pRasterVar3->set_ShortItemValue(7, 0);

//Fill in the rest of the comment, starting at the end->
for (i = 8; i<= (MyCommentSize - 1); i++)
{
TmpString = MyCommentText.SubString(i-7, 1);
  pRasterVar3->set_ShortItemValue(i, Byte (TmpString[1]));
}
 pRasterVar3->set_ShortItemValue(MyCommentSize, Byte (0));

//Update the user comment.
pMyRasterIO->set_Comment (CMNT_USERCOMMENT, pRasterVarEmpty);
pMyRasterIO->set_Comment(CMNT_USERCOMMENT, pRasterVar3);
//Save the file and read the comments that we saved.
pMyRasterIO->Save(LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), FILE_EXIF, 24, (QFactorConstants)0, SAVE_OVERWRITE);
pRasterVar1= pMyRasterIO->ReadComment (LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), 1, CMNT_SZDATETIMEDIGITIZED);
pRasterVar2= pMyRasterIO->ReadComment(LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), (short)1, CMNT_SUBJECTDISTANCE);
pRasterVar3= pMyRasterIO->ReadComment(LEADRasterView1->Raster, AnsiToOLESTR(FilePath.c_str()), (short)1, CMNT_USERCOMMENT);

//Interpret the Subject-Distance RATIONAL.
DistanceString = FloatToStr((float)(pRasterVar2->get_LongItemValue(0)/pRasterVar2->get_LongItemValue(1)));

//Initialize the string for the message box->
MyMsg = "Subject Distance = " + DistanceString + "\nDate/Time = " + pRasterVar1->StringValue;
//Add the ASCII comment if it is there
if( pRasterVar3->get_ShortItemValue(0) == Byte ("A"))
{
  ArraySize = pRasterVar3->ItemCount;
for (i = 8; i <= ArraySize; i ++)
   {
  NewCommentText = NewCommentText + (char)(Integer(pRasterVar3->get_ShortItemValue(i)));
  }
  MyMsg = MyMsg + "\n\n" + NewCommentText;
 }

//Display the message->
 Application->MessageBox(MyMsg.c_str(), "File Comments", MB_OK);
//Clear the comments from memory
for (i = 0; i <= CMNT_LAST; i ++)
pMyRasterIO->set_Comment ((short)i, pRasterVarEmpty);

 if ( pMyRasterProcess )
 pMyRasterProcess-> Release( );

 if ( pMyRasterIO )
 pMyRasterIO-> Release( );

 if ( pRasterVarEmpty )
 pRasterVarEmpty-> Release( );

 if ( pRasterVar1 )
 pRasterVar1-> Release( );

 if ( pRasterVar2 )
 pRasterVar2-> Release( );

 if ( pRasterVar3 )
 pRasterVar3-> Release( );

}