accessing UIImage properties without loading in memory the image

后端 未结 3 1805
余生分开走
余生分开走 2020-12-07 15:53

As you know the iphone guidelines discourage loading uiimages that are greater than 1024x1024.

The size of the images that i would have to load varies, and i would l

相关标签:
3条回答
  • 2020-12-07 16:40

    In Swift 5, with ImageIO,

    extension URL{
        var sizeOfImage: CGSize?{
            guard let imageSource = CGImageSourceCreateWithURL(self as CFURL, nil)
                , let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [AnyHashable: Any]
                , let pixelWidth = imageProperties[kCGImagePropertyPixelWidth as String] as! CFNumber?
                , let pixelHeight = imageProperties[kCGImagePropertyPixelHeight as String] as! CFNumber?
                else {
                    return nil
            }
            var width: CGFloat = 0, height: CGFloat = 0
            CFNumberGetValue(pixelWidth, .cgFloatType, &width)
            CFNumberGetValue(pixelHeight, .cgFloatType, &height)
           }
           return CGSize(width: width, height: height)
        }
    }
    

    imageProperties[kCGImagePropertyOrientation as String] may be nil.

    It is nil, I tested with png image file

    as Apple says

    kCGImagePropertyOrientation

    The numeric value for this key encodes the intended display orientation for the image according to the TIFF and Exif specifications.

    0 讨论(0)
  • 2020-12-07 16:43

    Swift 3 version of the answer:

    import Foundation
    import ImageIO
    
    func sizeForImage(at url: URL) -> CGSize? {
    
        guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil)
            , let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [AnyHashable: Any]
            , let pixelWidth = imageProperties[kCGImagePropertyPixelWidth as String]
            , let pixelHeight = imageProperties[kCGImagePropertyPixelHeight as String]
            , let orientationNumber = imageProperties[kCGImagePropertyOrientation as String]
            else {
                return nil
        }
    
        var width: CGFloat = 0, height: CGFloat = 0, orientation: Int = 0
    
        CFNumberGetValue(pixelWidth as! CFNumber, .cgFloatType, &width)
        CFNumberGetValue(pixelHeight as! CFNumber, .cgFloatType, &height)
        CFNumberGetValue(orientationNumber as! CFNumber, .intType, &orientation)
    
        // Check orientation and flip size if required
        if orientation > 4 { let temp = width; width = height; height = temp }
    
        return CGSize(width: width, height: height)
    }
    
    0 讨论(0)
  • 2020-12-07 16:50

    As of iOS 4.0, the iOS SDK includes the CGImageSource... functions (in the ImageIO framework). It's a very flexible API to query metadata without loading the image into memory. Getting the pixel dimensions of an image should work like this (make sure to include the ImageIO.framework in your target):

    #import <ImageIO/ImageIO.h>
    
    NSURL *imageFileURL = [NSURL fileURLWithPath:...];
    CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
    if (imageSource == NULL) {
        // Error loading image
        ...
        return;
    }
    
    CGFloat width = 0.0f, height = 0.0f;
    CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
    
    CFRelease(imageSource);
    
    if (imageProperties != NULL) {
    
        CFNumberRef widthNum  = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
        if (widthNum != NULL) {
            CFNumberGetValue(widthNum, kCFNumberCGFloatType, &width);
        }
    
        CFNumberRef heightNum = CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
        if (heightNum != NULL) {
            CFNumberGetValue(heightNum, kCFNumberCGFloatType, &height);
        }
    
        // Check orientation and flip size if required
        CFNumberRef orientationNum = CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation);
        if (orientationNum != NULL) {
            int orientation;
            CFNumberGetValue(orientationNum, kCFNumberIntType, &orientation);
            if (orientation > 4) {
                CGFloat temp = width;
                width = height;
                height = temp;
            }
        }
    
        CFRelease(imageProperties);
    }
    
    NSLog(@"Image dimensions: %.0f x %.0f px", width, height);
    

    (adapted from "Programming with Quartz" by Gelphman and Laden, listing 9.5, page 228)

    0 讨论(0)
提交回复
热议问题