How To Read EXIF Orientation From JPEG in Qt 4.8.5

For many Qt lovers out there who might want to use third-party EXIF parsing library with their Qt apps, it may prove difficult unless you know what you’re doing. If you’re a hobbyist like me, man, it’s just tough. But there are free EXIF parsers out there, and it might take a little elbow grease to make it work with Qt. In my case, I put together a very simple and basic image viewer that I thought users might appreciate if it auto-rotated any images that contained EXIF metadata such as orientation. In smartphones and DSLRs, there is usually a sensor that records which orientation the picture was taken in. So when you view the photo without orientation applied, it might be a minor nuisance having to manually rotate it. That’s where you come in as software developer and take care of it for the end-user.

So I found this chunk of free code at http://imonad.com/photo/jpeg-exif-orientation/ who claims this EXIF parsing code will work with Qt. Indeed it does to a point. But I had to go bug hunting because the code kept return an orientation value of 0, which isn’t valid anyway, the official values are 1 to 8. And this is the bug I found:


int Exif::processEXIF(QByteArray *data, int itemlen, int *Orientation) {
...

    if (data->mid(6,2) == "II") { // Exif section in Intel order
        //qDebug() << data->mid(6,2);
        MotorolaOrder = 0;
    } else {
        if (data->mid(6,2) == "II"){ // Exif section in Motorola order
            //qDebug() << data->mid(6,2);
            MotorolaOrder = 1;
        } else {
            return -1; // Invalid Exif alignment marker.
        }
    }

...


Can you spot the bug? If not, pay attention to that if-then code block. Notice the redundant condition if (data->mid(6,2) == "II")... in the else code block. If the opening if condition was already proven false, why would it be true as an opposite condition. In this case, it would always return -1, so the rest of the source code won’t even get past this code block. So to fix this, you have to remove that redundant chunk of code, like so:


int Exif::processEXIF(QByteArray *data, int itemlen, int *Orientation) {
...

    if (data->mid(6,2) == "II") { // Exif section in Intel order
        //qDebug() << data->mid(6,2);
        MotorolaOrder = 0;
    } else {
        MotorolaOrder = 1;
    }

...


And wouldn’t you know it, then it runs like a charm!!! You’re very welcome!

You can download the optimized source code, which I personally cleaned up, here:

And this is how you would use it in Qt 4.8.5 at least:


#include <QFile>
#include "exif.h"

QString filePath = "c:/image.jpg";
QFile file(filePath);
if (file.open(QIODevice::ReadOnly) == true) {
   Exif *exif = new Exif();
   int orientation = 0;
   exif->readJpegSections(file, &orientation);
   file.close();

   //do something with variable orientation
   if (orientation == 8) {
      //rotate image -90 degrees
   }
}

Happy coding! I’m sure you can probably even go deeper and extract more EXIF tags, but that’s beyond my understanding. You could extract embedded thumbnails too, but there have been cases the thumbnail doesn’t match the actual data anymore once it’s modified, so even embedded EXIF thumbnails become unreliable. Otherwise, I think orientation and maybe even the comments are quite useful. Who knows, someone has to find it all useful. LOL.

This entry was posted in Qt and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *