BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
art297
Opal | Level 21

Ksharp,  Please try it again with the following code.  There was definitely something wrong with the code, particularly how it identified a second set of tags:

%let path=c:\art\;

options datestyle=ymd;

proc format;

  value ttwo  18761='pibr2.'

              19789='s370fpib2.';

  value tfour 18761='pibr4.'

              19789='s370fpib4.';

run;

filename indata pipe "dir &path.*.jpg /b";

data want (keep=picture dt_taken coordinates title

                width height);

  length fil2read title $80;

  retain _exif_pattern_num;

  format dt_taken datetime19.;

  format lat lon $1.;

  length coordinates $35;

  infile indata truncover;

  if _n_ = 1 then _exif_pattern_num=

   PRXPARSE("/\x45\x78\x69\x66/");

  informat f2r $50.;

  input f2r;

  fil2read="&path."||f2r;

  done=0;

  infile dummy filevar=fil2read RECFM=n lrecl=12000

    end=done;

  picture=fil2read;

  do while(not done);

    input VAR1 $char12000.;

    POSITIONX = PRXMATCH(_EXIF_PATTERN_NUM,var1)+6;

    endian2=put(input(substr(var1,positionx,2),pibr2.),ttwo.);

    endian4=put(input(substr(var1,positionx,2),pibr2.),tfour.);

    numberx=inputn(substr(var1,positionx+inputn(substr(

     var1,positionx+4,4),endian4),2),endian2);

    offset=positionx+inputn(substr(var1,positionx+4,4),

     endian4)+2;

    gps_offset=0;

    subject_offset=0;

    date_offset=0;

    last_offset=0;

    do i=0 to numberx-1;

      xtag=inputn(substr(var1,offset+i*12,2),endian2);

      if xtag eq 34665 then do;

        numberx2=positionx+inputn(substr(

         var1,offset+i*12+8,4),endian4);

        last_offset=positionx+inputn(substr(

         var1,offset+i*12+8,4),endian4)+2;

      end;

      else if xtag eq 34853 then do;

        gps_bytes=inputn(substr(var1,offset+i*12+2,2),

         endian2);

              if gps_bytes eq 2 then gps_offset=positionx+

         inputn(substr(var1,offset+i*12+10,2),endian2);

              else gps_offset=positionx+

         inputn(substr(var1,offset+i*12+8,4),endian4);

      end;

      else if xtag eq 40091 then do;

        title_offset=positionx+inputn(substr(

         var1,offset+i*12+8,4),endian4);

        title_length=inputn(substr(

         var1,offset+i*12+4,4),endian4);

      end;

    end;

    if last_offset then do;

      do i=0 to numberx2-1;

        xtag=inputn(substr(var1,last_offset+i*12,2),endian2);

        if xtag eq 36867 then date_offset=

          inputn(substr(

           var1,last_offset+i*12+8,4),endian4);

        else if xtag eq 40962 then width=

          inputn(substr(

           var1,last_offset+i*12+8,4),endian4);

        else if xtag eq 40963 then height=

          inputn(substr(

           var1,last_offset+i*12+8,4),endian4);

     end;

    end;

    if title_offset then title=compress(input(substr(

     var1,title_offset,title_length),$50.),

     "/ ?+#$%&","knp");

    else title="No Title";

    if gps_offset then do;

      numberx=inputn(substr(var1,gps_offset,2),endian2);

      offset=gps_offset+2;

      do i=0 to numberx-1;

        xtag=inputn(substr(var1,offset+i*12,2),endian2);

        if xtag eq 1 then lat=input(substr(

         var1,offset+i*12+8,1),$1.);

        else if xtag eq 2 then do;

          lat_offset=positionx+inputn(substr(var1,

           offset+i*12+8,2),endian4);

          latdeg=inputn(substr(var1,lat_offset+ 0,4),endian4)/

                 inputn(substr(var1,lat_offset+ 4,4),endian4);

          latmin=inputn(substr(var1,lat_offset+ 8,4),endian4)/

                 inputn(substr(var1,lat_offset+12,4),endian4);

          latsec=inputn(substr(var1,lat_offset+16,4),endian4)/

                 inputn(substr(var1,lat_offset+20,4),endian4);

        end;

        else if xtag eq 3 then lon=input(substr(

         var1,offset+i*12+8,1),$1.);

        else if xtag eq 4 then do;

          lon_offset=positionx+inputn(substr(var1,

           offset+i*12+8,2),endian4);

          londeg=inputn(substr(var1,lon_offset+ 0,4),endian4)/

                 inputn(substr(var1,lon_offset+ 4,4),endian4);

          lonmin=inputn(substr(var1,lon_offset+ 8,4),endian4)/

                 inputn(substr(var1,lon_offset+12,4),endian4);

          lonsec=inputn(substr(var1,lon_offset+16,4),endian4)/

                 inputn(substr(var1,lon_offset+20,4),endian4);

        end;

      end;

      coordinates=strip(put(latdeg,best12.))||" "||

      strip(put(latmin,best12.))||"' "||

      strip(put(latsec,best12.))||'" '||

      strip(lat)||","||

      strip(put(londeg,best12.))||" "||

      strip(put(lonmin,best12.))||"' "||

      strip(put(lonsec,best12.))||'" '||

      strip(lon);

    end;

    else coordinates="No GPS";

    if date_offset then dt_taken=

     input(substr(var1,positionx+date_offset,19),anydtdtm19.);

    else dt_taken=0;

    output;

    done=1;

  end;

run;

art297
Opal | Level 21

Ksharp,  One additional note: DON'T use window's explorer to modify the jpg file.  It has a tendency to REALLY corrupt the exif portion of the file.  Usually will only affect the height, width and date settings (at least regarding the settings that my code is attempting to parse) but, other than title and gps coordinates, those are the only fields I am trying to extract.

A MUCH safer way of changing the file's attributes is to use one of the proven perl-based routines, such as

http://www.sno.phy.queensu.ca/~phil/exiftool/) which, by the way, is free and has a windows executable version.


sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 16 replies
  • 1531 views
  • 3 likes
  • 3 in conversation