{"id":44974,"date":"2015-04-30T07:00:00","date_gmt":"2015-04-30T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2015\/04\/30\/how-can-i-tell-if-a-file-is-an-image-of-some-type\/"},"modified":"2019-03-13T12:15:06","modified_gmt":"2019-03-13T19:15:06","slug":"20150430-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150430-00\/?p=44974","title":{"rendered":"How can I tell if a file is an image of some type?"},"content":{"rendered":"<p>A customer wanted to know if there is some standard way of determining from the full path to a file whether it is a photo or image. They are writing a program that transfers a bunch of files to a back-end server, and they want to treat photos differently from other files. <\/p>\n<p>You can use <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb773463(v=vs.85).aspx\">the <code>Assoc&shy;Get&shy;Perceived&shy;Type<\/code> function<\/a> to classify a file into one of a variety of categories. You can <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/bb762520(v=vs.85).aspx\">consult the document to see the full list<\/a>, but it&#8217;s things like &#8220;image&#8221;, &#8220;audio&#8221;, &#8220;video&#8221;, &#8220;document&#8221;. This information is obtained by studying the file extension and looking up <a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/cc144148(v=vs.85).aspx\">the registered perceived type<\/a>. <\/p>\n<p>Let&#8217;s take the function out for a spin: <\/p>\n<pre>\n#define UNICODE\n#define _UNICODE\n#include &lt;windows.h&gt;\n#include &lt;shlwapi.h&gt;\n#include &lt;stdio.h&gt; \/\/ horrors! mixing C and C++!\n\nint __cdecl wmain(int argc, wchar_t **argv)\n{\n PERCEIVED perceived;\n PERCEIVEDFLAG flag;\n PWSTR pszType;\n if (argc &gt; 1 &amp;&amp; SUCCEEDED(AssocGetPerceivedType(\n    PathFindExtensionW(argv[1]),\n    &amp;perceived, &amp;flag, &amp;pszType)))\n {\n  wprintf(L\"Type is %ls\\n\", pszType);\n  if (perceived == PERCEIVED_TYPE_IMAGE) {\n   wprintf(L\"Hey, that's an image!\\n\");\n  }\n  CoTaskMemFree(pszType);\n }\n return 0;\n}\n<\/pre>\n<p>Run this program and give a file name, or just an extension (with the dot) as the command line parameter. It will tell you the perceived type and include a special message if the type is an image. <\/p>\n<p>But let&#8217;s look at the customer&#8217;s question again. It&#8217;s not clear whether they are trying to identify files by file format or by classification. For example, suppose the file in question is a <a HREF=\"http:\/\/en.wikipedia.org\/wiki\/Tagged_Image_File_Format\">TIFF<\/a> image. The <code>Assoc&shy;Get&shy;Perceived&shy;Type<\/code> function will report this as an image, because, well, it&#8217;s an image. But that may not be a file format that their back-end server supports. <\/p>\n<ul>\n<li>If they wanted to know whether the file is a PNG, GIF, or JPG     because those are the image formats supported by their     back-end server,     then they need to check for those specific extensions     (and possibly even sniff file contents if they are paranoid). \n<li>If they care only that the file represents some sort of image     (possibly in a format their program does not know how to parse),     because they want to, say, upload all images into a Pictures folder     regardless of the image format,     then they should use the Perceived Type. <\/ul>\n<p>The customer thanked us for the pointer to the <code>Assoc&shy;Get&shy;Perceived&shy;Type<\/code> function and especially for the clarifying remarks. &#8220;It turns out that the feature specification was not clear on the definition of &#8216;image file&#8217;, so that&#8217;s something we will need to resolve ourselves. But the information you provided will definitely solve our problem, once we figure out what our problem is!&#8221; <\/p>\n","protected":false},"excerpt":{"rendered":"<p>The perceived type tells you what kind of file it is, for a very general sense of the word &#8220;kind&#8221;.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-44974","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The perceived type tells you what kind of file it is, for a very general sense of the word &#8220;kind&#8221;.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=44974"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44974\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=44974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=44974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=44974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}