accessing UIImage properties without loading in memory the image

cgimagesourcecopypropertiesatindex
swift load image from path
uiimageview array of images
swift load image from assets
cgimagesourcecreateimageatindex
uiimageview set image swift 4
uiimage(named swift)
swiftui image to uiimage

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 like to check the size of the image i am about to load; however using the .size property of uiimage requires the image to be laoded... which is exactly what i am trying to avoid.

Is there something wrong in my reasoning or is there a solution to that?

thank you all

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)

Accessing Image Properties Without Loading the Image Into Memory , The simplest way to do that on iOS is using the UIImage class: UIImage *image = [UIImage imageWithContentsOfFile:];� Accessing Image Properties Without Loading the Image Into Memory Sometimes you might want to retrieve certain properties from an image file, such as the image’s dimensions or other metadata, without actually displaying the full-size image on screen. The simplest way to do that on iOS is using the UIImage class:

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)
}

Loading images with UIImage, This property will be a string – the name of the image to load – but it needs to be an optional will automatically destroy the old view controller and free up its memory. and Swift doesn't let you use these “maybes” without checking them first. In addition to loading images from disk, you can ask the user to supply images from an available camera or photo library using a UIImage Picker Controller object. An image picker displays a custom user interface for selecting images. Accessing user-supplied images requires explicit user permission.

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.

UIImage, You use image objects to represent image data of all kinds, and the UIImage class is capable of These methods load the image data from disk each time, so you should not use them to Most image properties are set automatically using metadata in the Accessing user-supplied images requires explicit user permission. I'm loading a UIImage from NSData with the following code. var image = UIImage(data: data!) However, there is a weird behavior. At first, I used png data, and the NSData was about 80kB each. When I set UIImage with the data, the UIImage took up 128kb each. (Checked with Allocation instrument, the size of ImageIO_PNG_Data)

imageNamed:, Creates an image object from the specified named asset. + (UIImage *) imageNamed:(NSString *)name; You cannot use this method to load system symbol images; use the systemImageNamed: method instead. images out of the system image cache can potentially improve the memory use characteristics of your app. However, the handler provides a UIImage object and the Task must return a .NET Stream object. This is done in two steps: The UIImage object is first converted to an in memory PNG or JPEG file stored in an NSData object, and then the NSData object is converted to a .NET Stream object.

UIImage Optimization. When do we need to use UIImage(named , and make sure you're reloading the image when the backing file is changed. the fact that you can't access files outside of the application bundle. image cache, potentially improving the memory use characteristics of On Medium, smart voices and original ideas take center stage - with no ads in sight. In actual fact, there are three main techniques available to handle image files in tables with MS Access and these are: Store the image in an OLE field and use a bound object frame to display the image. Store the path to the image in a text field, using an image control to display the image. Store the image as a binary large object bitmap (BLOB

Downsampling images for better memory consumption and , Moreover, Apple recommends using UIImage and UIImageView to display the Load compressed image data to memory. This means scalability without losing sharpness and quality. An image source can contain more than one image, thumbnail images, properties for each image, and the image file. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated. Add / Remove / Fetch Images

Comments
  • This is a good question. Android provides a means to do this, but I don't know of an iOS solution offhand. EDIT: This has been asked before. stackoverflow.com/questions/1551300/…
  • i searched before, but i couldn't find it! many thanks!
  • Why use CGImageSourceCopyPropertiesAtIndex instead of just CGImageSourceCopyProperties?
  • It is very important to pass kCFNumberCGFloatType instead of kCFNumberFloatType when calling CFNumberGetValue() since the variables width and height are declared as CGFloat. The code above will work on 32-bit systems but the values will contain garbage on 64-bit systems.
  • @fjoachim: Thanks, fixed.
  • @OleBegemann Should also take image orientation (kCGImagePropertyOrientation) into account - flip width and height for orientations 5 to 8. You can test with these images.
  • does it support remote image or only support local image?
  • Small detail: I am finding that imageProperties[kCGImagePropertyOrientation as String] may be nil for some images.