CCR Exif v1.5.3 + Android app based on it in Google Play

Recently I have committed some updates to CCR Exif (my open source image metadata parsing library) that get it working with Delphi XE5, and in particular, Delphi for Android. In the main, that wasn’t hard to do – in one place I’d (mis)used the Objects property of a TStrings instance to hold casted enum values, which is a no-no under ARC, but otherwise things (with the odd [Weak] added) were fine. Well, fine with one major caveat: the code needs Andreas Hausladen’s patch to restore AnsiChar, PAnsiChar and UTF8String. Bluntly, if support for those types really does go away in XE6, then I’ll just have to say the code will support Delphi for mobile in XE5 and XE5 only, because I’m not going to crappify it.

The whole issue is a shame, because the general language and RTL compatibility between platforms (Windows/OS X/iOS/Android) and frameworks (FMX/VCL) is excellent. For example, for reading XMP metadata, my Exif code uses the IDOMxxx interfaces, the lower-level counterpart to the rather more heavyweight TXMLDocument. Both are available to use whatever the platform. Another example: at various points the FMX platform code for Android needs to wait on another thread (the Java thread) finishing a method call. What does it use for the task? Why, TEvent, using exactly the same method calls you might have made in a VCL project ten years ago.

Anyhow, proof of the pudding, I’ve written up an Exif editing app and put it on Google Play – it’s called Exif Inspector and is available here:

Brickbats welcomed, partly because you’ll have to pay a small amount to make them 😉

Cross platform FMX/XE3 demos for CCR Exif

I’ve just added a set of FMX demos in the SVN trunk for my image metadata reading/writing library, CCR Exif. These are ports of the existing VCL demos (minus the resaving tester). In alphabetical order, they number the following:

  • ExifList displays the Exif tags from an image, Exif being the metadata format most cameras use.
  • ExifTimeShifter shifts the Exif date/times for one or more images by a specified number of minutes.
  • IPTCEditor edits the IPTC data held in an image. IPTC is the metadata format Photoshop used back in the 1990s, and makes for a slightly lower-tech alternative to Exif.
  • JpegDump displays information from a JPEG file’s header, providing a lower-level view of its metadata tags than the other demos.
  • Screenshooter takes a screenshot, applies a few tags, and saves to a new JPEG file.
  • XMPBrowser displays XMP metadata in a tree view, XMP being a newer, XML-based metadata format.

While the FMX demos (which require XE3 by the way) mostly hew to the line set by their VCL forebears, I began with a blank slate in each case. This I did because I wanted certain UI details to follow the target platform (i.e., Windows or OS X), and in so doing, see what FMX did to help, or at least, see how far it wouldn’t get in the way.

Screenshooter and ExifTimeShift

The simplest demo to port was Screenshooter, since the FMX version has almost exactly the same UI for both platforms. The only difference is the fact the Mac version has the regular Mac menu bar; however, the menu items on it are just the standard ones that FMX in XE3 set up for you automatically:

Similar between platforms too is ExifTimeShift:

In this case there are some subtle differences though:

  • I hide a few toolbar buttons on OS X because toolbars on a Mac just tend to have less items than their Windows equivalents.
  • The Preferences/Options dialog is non-modal on OS X, with no explicit OK/Cancel buttons and changes applied immediately. (I leave aside whether this makes for a better UI – in fact, I think I prefer the Windows model myself – but that is the contemporary Apple style.)
  • On both platforms, double clicking a listed file displays the image. On Windows the image window gets its own taskbar button; on OS X it is full screen-enabled – you can see this in the screenshot with the double arrow icon on the title bar – and listed under the application’s Window menu. While I had to implement these things manually, it wasn’t hard, though I’d admit the Windows part requires more work (the FMX developers are unfortunately obsessed with a Win 3.x/VCL-style ‘main form’ concept that isn’t technically native even on Windows).
  • The file date/time preference is saved to the Registry on Windows and the application’s preferences file on OS X. Since I didn’t want to introduce dependencies, the latter is done by direct API calls, though in practice I would use my own Mac Preferences API wrapper I blogged about previously.

ExifList, IPTCEditor and XMPBrowser

The main platform difference between the remaining demos is much more ‘in your face’: whereas on Windows the applications are SDI, on OS X they follow the basics of the Mac document model. As such, if you run ExifList, IPTCEdit or XMPBrowser on OS X without passing the application a file first, it opens with no window showing. This follows what Preview does:

Further, whereas the same instance of the Mac version can have multiple images open, each with their own window (and enumerable using the system-standard Cmd+` shortcut), you need to open the Windows version several times to have it load several images at the same time:


Each demo is essentially single source, and structured around my preferred VCL UI model. In this, the document form’s OnClick code is all centralised into action lists located on a data module separate from the form itself, with any necessary communication between the actions and the form being performed via interface types. A unit shared between all the demos (CCR.FMX.Demos.pas) then contains all the platform-specific UI-related code, and manages the differences between the different document models (no form is auto-created in the traditional Delphi fashion, and the document form class itself is looked up using RTTI). Alas, but that unit also implements certain crucial bug fixes for FMX itself, though at least the new IFMXxxxService system (see my previous-but-one post) made that bareable. I’ll probably blog about it in more detail later.

New release of my image metadata reading/writing code (CCR Exif v1.5.1)

Rather belatedly, given the code has been sitting in the SVN trunk for many months, I’ve finalised a new ‘stable’ release of my image metadata reading/writing library, CCR Exif (despite its name, it has some support for IPTC and XMP metadata too). If people using it have been updating from the Google Code repository, the only real change is the removal of the word ‘beta’ from the file headers, however I did put through an important bug fix concerning XMP writing not so long ago. I’ve also put up a new ZIP file for people who prefer that, however I would recommend using the SVN repository instead (I only commit bug fixes and structural changes I’m sure I won’t reverse).

Going forward, I won’t be supporting the Delphi 2006 compiler any more, and possibly later ones too – we’ll see. This 1.5.1 version will still be available for old compilers however.

[Update: soon after I posted it, someone spotted a few incompatibilities between v1.5.1 and D2006. Because of that, there will be a v1.5.2 that supports D2006. Use the trunk version if you want D2006 support now, though really, it may be time to think about upgrading…]

XE2 update for my image metadata reading/writing library (CCR Exif)

I was going to get round to it eventually, though having an explicit request prompted me to actually do it: updating my open source image metadata reading/writing library (CCR Exif) to properly support XE2. The updates I’ve just posted to Google Code has it cross compiling for each of Delphi XE2’s three DCC-targeting platforms, Win32, Win64 and OS X; it should also still compile back to D2006, though at least D2007, and preferably D2009 are preferred. On the downside, iOS isn’t supported because the code remains as Delphi-specific as ever (and no, FPC 2.6.0 doesn’t help much). Also, there aren’t any FireMonkey demos as yet, though the console ones all cross compile if you have XE2 and add OS X as a target platform.

In practical terms, Win64 took as long as it took to add ‘Win64’ as a target for each of the demos; OS X was somewhat longer for a mixture of reasons, primarily because the code had some entanglement with the VCL graphics classes, and there’s no ‘clean’ way for the same code to work with both VCL and FMX on that score. By far the biggest waste of time effort was managing project files across an array of Delphi versions though, with battling Subversion a close second, i.e. not actual coding at all. As I wanted to make running the demos as newbie-friendly as possible, I’ve ended up with separate project files for D2006, D2007, D2009-10 and XE+ – just open the appropriate project group located at the top of the trunk and do a Project|Compile All. If compiling under D2007 or later, executables will then be outputted in a sub-directory off the Bin folder next to the individual projects, and DCUs in a ‘DCUs’ folder off of the main trunk.

Anyhow, the Google Code page is here; if using the File|Open From Version Control… command in the XE or XE2 IDE, the URL to enter is; choose either Console Demos (XE+).groupproj or VCL Demos (XE+).groupproj as appropriate when prompted.

[Update: for information about v1.5.1, please see here.]

Small revision of my Exif code (v1.1.2)

I’ve formalised the changes to my Exif reading/writing code I’ve made since the last minor release, so it’s now at v1.1.2. For the individuals who’ve been using the trunk version, there’s no changes beyond updated file headers. Nonetheless, I’ve tagged this release in the repository and uploaded ZIPs for both it and all previous releases to Google Code (see here).

Because of the latter, I’ve also deleted the CodeCentral entries (two less things to remember to update…). Lastly, at some point I’ll get round to updating the trunk with my working version, which has a fair bit of rejigging internally to support a few more image formats beyond JPEG, and consequently, a few interface changes (not many though).

[Edit: I’ve now updated the trunk with the 1.5.0 beta code, the main structural change being CCR.Exif.JPEGUtils.pas effectively replaced with CCR.Exif.BaseUtils.pas and CCR.Exif.TiffUtils.pas (the new image formats supported are PSD and TIFF by the way, the various LoadFromJPEG and SaveToJPEG methods being deprecated and replaced with LoadFromGraphic and SaveToGraphic ones). Along with the usual bug reports, I will be pleased to receive any reports of the new code working successfully in the comments below, especially from individuals who have used older versions.]

[Edit 2: while I’ve now closed the comments, feel free to continue any discussions under this post.]

New version of my Exif parsing code (v1.1.1)

I’ve put up a slight revision on my Exif and IPTC parsing code. The changes aren’t drastic —

  • Tweaked default behaviour of file name variants of TCustomExifData.SaveToJPEG and TIPTCData.SaveToJPEG to write to a memory stream first. This protects against the case of when the file exists, but is not a valid JPEG file (before, the file would just get wiped on the exception being raised).
  • Added EnsureEnumsInRange property to TCustomExifData. When True (the default), enumeration tag property values will definitely be in the declared range — if the stored value is otherwise, it will be reported as missing unless you get at the raw data directly.
  • Slightly modified TXMPPacket.TryLoadFromStream to support ExifTool’s not-quite-XMP XML dump format.

As before, it can be downloaded from CodeCentral here.

[Edit: now on Google Code here; ZIPs for people who don’t like Subversion here. Since this post was written, I’ve released v1.1.2 — see here, where comments will remain open until the next release.]