New CCR Exif release (now v1.1.0)

I’ve just put up another revision of my Exif parsing/writing code. This release centres on improving how XMP packets are read and written (more details here), so there’s no interface changes of any significance. Anyhow, the download location is the same as always.

Advertisements

15 thoughts on “New CCR Exif release (now v1.1.0)

  1. Subject: Canon MakerNote Tag Values

    Are there errors in some Canon MakerNote Values, or is it just me that don’t understand data conversions?

    I get similar differences in images from both Canon PowerShot SX1 IS and PowerShot A620 cameras.

    Some Tag examples (values from Phil Harvey’s Exiftool in parenthesis):
    MakerNote
    ISO speed 15 (50)
    Auto ISO speed 0 (100)
    Base ISO speed 128 (50)
    Aperture (F number) 120 (3.564/Exif – 3.668/Canon:FNumber)
    Maximum aperture 95 (2.798)
    Minimum aperture 192 (8)
    Shutter speed 192 (0.015625/Canon:ExposureTime)
    MeasuredEV 2 (->MeasuredLV) 197 (11.156)
    Target Aperture 116 (3.564)
    Target shutter speed 189 (0.01667/ TargetExposureTime)
    Exposure compensation 65524/or -12 (0.333/Canon:ExposureCompensation)
    Flash guide number 162 (5.0625/ Canon:FlashGuideNumber)
    Bulb duration 2 (0)

    I would also like to get the Exif:ImageWidth / ImageHeight tag values.

    • Ola –

      Are there errors in some Canon MakerNote Values, or is it just me that don’t understand data conversions?

      Without having a sample image to put through the debugger, your guess is as good as mine. If you put one up somewhere, I’ll have a look if you like (ideally it would be the one you’ve listed those values for).

      I would also like to get the Exif:ImageWidth / ImageHeight tag values.

      If you’re referring to the standard tags, then they are surfaced as the ExifImageWidth and ExifImageHeight properties. If you mean custom maker note tags, then MakerNotes.ini would need updating (there’s no particular magic in how the Exif List demo works – maker note tag names and values are directly mapped from the INI file).

  2. Thanks. Please mail me your address, and I will send sample image(s) and further reference data.

    Br. Ola

  3. Thank you for a such good and well scratched component CCR Exif! I find the way to extract Longitude by using “ExifData.GPSLongitude.AsString” and it gives me (83,16,29997/500W) but the same data gives exiftool (83 Deg 16 Min 9999 Sec) . What formula use to calculate seconds in both case (29997/500W) =???= (9999 Sec) ? Thank you…

    • Hi Phil. If you want the data to be presented in a slighty different way, then just put the properties into a suitable Format or FmtStr call —

      function GPSCoordToStr(Coord: TGPSCoordinate): string;
      begin
        FmtStr(Result, '%g Deg %g Min %g Sec',
          [Coord.Degrees.Quotient, Coord.Minutes.Quotient, Coord.Seconds.Quotient]);
      end;
      ...
      ShowMessage(GPSCoordToStr(ExifData.GPSLongitude));
      

      However, this will still result in a different figure for Secs, as you’ve seen. Dare I say it, but is this an ExifTool bug? At least, ‘9999 seconds’ doesn’t make sense to me given the ‘seconds’ are supposed to be fractions of a minute, and there are only 60 seconds in a minute (cf. how 29997/500/60=0.9999). What do other Exif tag readers report?

  4. Hi,
    I found a small issue in the great CCR Exif component. When calling “SaveToJPEG”, it may fail (if the target file is not JPEG). In such a case the program clears the content of the file completely which is not nice. A small code change will solve it:

    try
      InStream.LoadFromFile(JPEGFileName);
      OutStream := TFileStream.Create(JPEGFileName, fmCreate);
      SavingFailed:=true; // DMA
      DoSaveToJPEG(InStream, OutStream);
      SavingFailed:=false; // DMA
    finally
      // DMA, if saving failed, copy over the original data
      if SavingFailed then
      begin
        InStream.Seek(0,0);
        OutStream.CopyFrom(InStream, InStream.Size);
      end;
      // DMA, end
      InStream.Free;
    

    Otherwise the component is great and handy. Thanks!!

    BTW: Are the types really so strict?? Can we put to GPSLatitude simply the whole Latitude as string?

    Regards, David

    • Hi Dave —

      Interesting suggestion for the file name variant of SaveToJPEG, thanks. Given an exception might be raised in InStream.LoadFromFile though, how about this:

      procedure TExifData.SaveToJPEG(const JPEGFileName: string);
      var
        InStream: TMemoryStream;
        OutStream: TFileStream;
        NeedsRestoring: Boolean;
      begin
        NeedsRestoring := False;
        OutStream := nil;
        InStream := TMemoryStream.Create;
        try
          InStream.LoadFromFile(JPEGFileName);
          OutStream := TFileStream.Create(JPEGFileName, fmCreate);
          NeedsRestoring := True;
          DoSaveToJPEG(InStream, OutStream);
          NeedsRestoring := False;
        finally
          OutStream.Free;
          if NeedsRestoring then InStream.SaveToFile(JPEGFileName);
          InStream.Free;
        end;
      end;
      

      Alternatively, this could be done:

      procedure TExifData.SaveToJPEG(const JPEGFileName: string;
        BufferedWrite: Boolean = True);
      var
        InStream: TMemoryStream;
        OutStream: TStream;
      begin
        OutStream := nil;
        InStream := TMemoryStream.Create;
        try
          InStream.LoadFromFile(JPEGFileName);
          if BufferedWrite then
            OutStream := TMemoryStream.Create
          else
            OutStream := TFileStream.Create(JPEGFileName, fmCreate);
          DoSaveToJPEG(InStream, OutStream);
          if BufferedWrite then
            TMemoryStream(OutStream).SaveToFile(JPEGFileName);
        finally
          OutStream.Free;
          InStream.Free;
        end;
      end;
      

      What do you think?

      With respect to your other question, what format are you thinking of in particular? The AsString property (which as you’ve noticed, is read-only at the present) uses the XMP format, which may not be what you want even if I did add a setter.

      • 1) Compliments
        First compliments on the great EXIF, IPTC component set. It is the cleanest and best written library I have seen in this area.

        2) Erased Images
        I ran into the same file erased issue. Because of the heavy consequences in case of failure, I vote to default to the buffered write option which should be on by default. The restoration does not solve problem, it just works around it and can still lead to erased images if restoration action fails for whatever reason.

        Personally, I would totally remove the direct write option or rename it “DirectWriteImageMayBeErasedIfAnythingGoesWrong” to prevent people from coming back complaining about erased images.

        3) The SaveToJPEG() function also exists in the IPTC section and needs fixing there too.

        • Jan — thanks for reminding me (I’ve had the changes in my private version for a while). I’ll be putting up a revised version with that and a couple of other minor fixes soonish.

          • Hi CR,

            Do you have any plans to put the source code on Google Code or something similar?

            Currently, I am using a heavily modified version of the very old dexif library. I want to switch to CCRExif and may want to contribute as there are plenty of maker tags that need improved formatting.

          • I have used it, but never setup a new project. For educational purposes I tried to setup a new project and it took about 5 minutes.

            I took the liberty to create a project for CCR Exif:

            https://code.google.com/p/ccr-exif/

            I also uploaded the source code in subversion. There is a nice place for downloads and bug tracking too.

            If you want to use it, email me your gmail email address (a Google account is required) at info@digitaldutch.com and I will make you the site owner after which you can remove me.

  5. Thank you for doing what almost never happens. You have not only created a full-featured set of routines but you have included a good number of demos that — gasp! — loaded, built, and ran the first time without any fiddling at all. I mean, I just unzipped the zip file, started up Delphi 2006, loaded the project groups and every one of them ran! No embedded directories, broken links, nothing amiss at all. I can’t stop going on about this. Thanks so much. And the demos are not just quickies. I mean they even have exception handling. Wow! And, did I say it already? They all ran without tweaking! Thanks, again.

Comments are closed.