Using UTIs to Identify Image Files

Q: How can I use Uniform Type Identifiers (UTIs) to determine if a given file path is an image file?

A: You can determine if a given file, based on its file path, is an image file by comparing its UTI through the Launch Services framework with the supported UTIs from the Image I/O framework.

Listing 1: Determining if a file path is an image file.


- (BOOL)isImageFile:(NSString*)filePath
{
    BOOL isImageFile = NO;
    FSRef fileRef;
    Boolean isDirectory;

    if (FSPathMakeRef((const UInt8 *)[filePath fileSystemRepresentation], &fileRef, &isDirectory) == noErr)
    {
        // get the content type (UTI) of this file
        CFDictionaryRef values = NULL;
        CFStringRef attrs[1] = { kLSItemContentType };
        CFArrayRef attrNames = CFArrayCreate(NULL, (const void **)attrs, 1, NULL);

        if (LSCopyItemAttributes(&fileRef, kLSRolesViewer, attrNames, &values) == noErr)
        {
            // verify that this is a file that the Image I/O framework supports
            if (values != NULL)
            {
                CFTypeRef uti = CFDictionaryGetValue(values, kLSItemContentType);
                if (uti != NULL)
                {
                    CFArrayRef supportedTypes = CGImageSourceCopyTypeIdentifiers();
                    CFIndex i, typeCount = CFArrayGetCount(supportedTypes);

                    for (i = 0; i < typeCount; i++)
                    {
                        CFStringRef supportedUTI = CFArrayGetValueAtIndex(supportedTypes, i);

                        // make sure the supported UTI conforms only to "public.image" (this will skip PDF)
                        if (UTTypeConformsTo(supportedUTI, CFSTR("public.image")))
                        {
                            if (UTTypeConformsTo(uti, supportedUTI))
                            {
                                isImageFile = YES;
                                break;
                            }
                        }
                    }

                    CFRelease(supportedTypes);
                }

                CFRelease(values);
            }
        }

        CFRelease(attrNames);
    }

    return isImageFile;
}

If you require other UTIs not related to image files or ImageIO, in place of CGImageSourceCopyTypeIdentifiers() you may use the following -

CFArrayRef UTICreateAllIdentifiersForTag(CFStringRef inTagClass, CFStringRef inTag, CFStringRef inConfirmingToUTI);

Related Documentation

Back to Top 

Document Revision History

DateNotes
2007-05-11First Version

Posted: 2007-05-11


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.