{"id":295,"date":"2017-02-07T22:57:52","date_gmt":"2017-02-08T03:57:52","guid":{"rendered":"http:\/\/eastfist.com\/qt_tutorials\/?p=295"},"modified":"2017-08-26T03:25:14","modified_gmt":"2017-08-26T09:25:14","slug":"how-to-read-exif-orientation-from-jpeg-in-qt-4-8-5","status":"publish","type":"post","link":"https:\/\/eastfist.com\/qt_tutorials\/how-to-read-exif-orientation-from-jpeg-in-qt-4-8-5\/","title":{"rendered":"How To Read EXIF Orientation From JPEG in Qt 4.8.5"},"content":{"rendered":"<p>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&#8217;re doing. If you&#8217;re a hobbyist like me, man, it&#8217;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&#8217;s where you come in as software developer and take care of it for the end-user.<!--more--><\/p>\n<p>So I found this chunk of free code at <a href=\"http:\/\/imonad.com\/photo\/jpeg-exif-orientation\/\">http:\/\/imonad.com\/photo\/jpeg-exif-orientation\/<\/a> 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&#8217;t valid anyway, the official values are 1 to 8. And this is the bug I found:<\/p>\n<blockquote>\n<pre><code>\r\nint Exif::processEXIF(QByteArray *data, int itemlen, int *Orientation) {\r\n...\r\n\r\n    if (data-&gt;mid(6,2) == \"II\") { \/\/ Exif section in Intel order\r\n        \/\/qDebug() &lt;&lt; data-&gt;mid(6,2);\r\n        MotorolaOrder = 0;\r\n    } else {\r\n        if (data-&gt;mid(6,2) == \"II\"){ \/\/ Exif section in Motorola order\r\n            \/\/qDebug() &lt;&lt; data-&gt;mid(6,2);\r\n            MotorolaOrder = 1;\r\n        } else {\r\n            return -1; \/\/ Invalid Exif alignment marker.\r\n        }\r\n    }\r\n\r\n...\r\n\r\n<\/code><\/pre>\n<\/blockquote>\n<p>Can you spot the bug? If not, pay attention to that if-then code block. Notice the redundant condition <code>if (data-&gt;mid(6,2) == \"II\")...<\/code> in the <code>else<\/code> 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&#8217;t even get past this code block. So to fix this, you have to remove that redundant chunk of code, like so:<\/p>\n<blockquote>\n<pre><code>\r\nint Exif::processEXIF(QByteArray *data, int itemlen, int *Orientation) {\r\n...\r\n\r\n    if (data-&gt;mid(6,2) == \"II\") { \/\/ Exif section in Intel order\r\n        \/\/qDebug() &lt;&lt; data-&gt;mid(6,2);\r\n        MotorolaOrder = 0;\r\n    } else {\r\n        MotorolaOrder = 1;\r\n    }\r\n\r\n...\r\n\r\n<\/code><\/pre>\n<\/blockquote>\n<p>And wouldn&#8217;t you know it, then it runs like a charm!!! You&#8217;re very welcome!<\/p>\n<p>You can download the optimized source code, which I personally cleaned up, here:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.eastfist.com\/files\/exifForQt\/exif.h\">exif.h<\/a><\/li>\n<li><a href=\"http:\/\/www.eastfist.com\/files\/exifForQt\/exif.cpp\">exif.cpp<\/a><\/li>\n<\/ul>\n<p>And this is how you would use it in Qt 4.8.5 at least:<\/p>\n<blockquote>\n<pre><code>\r\n#include &lt;QFile&gt;\r\n#include \"exif.h\"\r\n\r\nQString filePath = \"c:\/image.jpg\";\r\nQFile file(filePath);\r\nif (file.open(QIODevice::ReadOnly) == true) {\r\n   Exif *exif = new Exif();\r\n   int orientation = 0;\r\n   exif-&gt;readJpegSections(file, &amp;orientation);\r\n   file.close();\r\n\r\n   \/\/do something with variable orientation\r\n   if (orientation == 8) {\r\n      \/\/rotate image -90 degrees\r\n   }\r\n}\r\n<\/code><\/pre>\n<\/blockquote>\n<p>Happy coding! I&#8217;m sure you can probably even go deeper and extract more EXIF tags, but that&#8217;s beyond my understanding. You could extract embedded thumbnails too, but there have been cases the thumbnail doesn&#8217;t match the actual data anymore once it&#8217;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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;re doing. If you&#8217;re a hobbyist like me, man, it&#8217;s just tough. But there are free EXIF parsers out there, and it might take a little elbow grease &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/eastfist.com\/qt_tutorials\/how-to-read-exif-orientation-from-jpeg-in-qt-4-8-5\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;How To Read EXIF Orientation From JPEG in Qt 4.8.5&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27],"tags":[16,22,85,97,99,98,100,3,101,102,19],"class_list":["post-295","post","type-post","status-publish","format-standard","hentry","category-qt-2","tag-4-8-5","tag-c","tag-code","tag-exif","tag-jpeg","tag-orientation","tag-parse","tag-qt","tag-read","tag-script","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/posts\/295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/comments?post=295"}],"version-history":[{"count":14,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/posts\/295\/revisions"}],"predecessor-version":[{"id":320,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/posts\/295\/revisions\/320"}],"wp:attachment":[{"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/media?parent=295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/categories?post=295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eastfist.com\/qt_tutorials\/wp-json\/wp\/v2\/tags?post=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}