Search code examples
firemonkeyc++builder

GPS file properties


I can find basic properties of a file with System.IOUtils.TFile like size, date etc. But, i can't figure how to get the GPS coordinates from a JPEG (latitude and longitude) in my C++ Builder FMX app for WIN32.

I can do it with a console application based on this GDI+ example from Microsoft. I just can't figure out how to do this up at System.IOUtils.TFile level. I don't want to run a console app to get the GPS data if don't have to.


Solution

  • You can open the exif data on your own ... This is my ancient C++/VCL code doing so:

    AnsiString exif_datetime(AnsiString file)
        {
        AnsiString t="";
        int hnd,adr,siz;
        BYTE *dat;
        hnd=FileOpen(file,fmOpenRead);
        if (hnd<0) return t;
        siz=FileSeek(hnd,0,2);
            FileSeek(hnd,0,0);
        dat=new BYTE[siz];
        if (dat==NULL) { FileClose(hnd); return t; }
        siz=FileRead(hnd,dat,siz);
        FileClose(hnd);
    
        for (adr=0;adr<siz-4;adr++)
            {
            if (dat[adr+0]=='E')
            if (dat[adr+1]=='x')
            if (dat[adr+2]=='i')
            if (dat[adr+3]=='f')
            if (dat[adr+4]== 0 )    // Exif header found
                {
                for (;adr<siz-18;adr++)
                    {
                    int e=1;
                    char a; // "2008:07:17 19:19:10"
                    a=dat[adr+ 0]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 1]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 2]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 3]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 4]; if (a!=':') e=0;
                    a=dat[adr+ 5]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 6]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 7]; if (a!=':') e=0;
                    a=dat[adr+ 8]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+ 9]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+10]; if (a!=' ') e=0;
                    a=dat[adr+11]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+12]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+13]; if (a!=':') e=0;
                    a=dat[adr+14]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+15]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+16]; if (a!=':') e=0;
                    a=dat[adr+17]; if ((a<'0')||(a>'9')) e=0;
                    a=dat[adr+18]; if ((a<'0')||(a>'9')) e=0;
                    if (e)
                        {
                        for (e=0;e<19;e++) t+=char(dat[adr+e]);
                        break;
                        }
                    }
                break;
                }
            }
    
        delete[] dat;
        return t;
        }
    

    It opens and loads JPG into memory, scan for EXIF structure and if found return date time from it ...

    So just extract info you want instead ofthe datetime ... on how to do it see:

    Its the first file format specs I found (from wiki).

    In case you got big images the EXIF in JPG is usually placed at the start of file so you do not need to load the whole image to memory just few first (K)Bytes ...