2010-11-12 3 views
18

Comme vous le savez les directives de l'iphone découragent le chargement des ui-images qui sont supérieures à 1024x1024.accéder aux propriétés UIImage sans charger l'image en mémoire

La taille des images que je devrais charger varie, et je voudrais vérifier la taille de l'image que je suis sur le point de charger; Cependant, l'utilisation de la propriété .size de uiimage nécessite que l'image soit déposée ... ce qui est exactement ce que j'essaie d'éviter.

Y at-il quelque chose qui ne va pas dans mon raisonnement ou existe-t-il une solution à cela?

vous remercie tous

+1

Ceci est une bonne question. Android fournit un moyen de le faire, mais je ne connais pas de solution iOS. EDIT: Cela a déjà été demandé. http://stackoverflow.com/questions/1551300/get-size-of-image-without-loading-in-to-memory – Justin

+0

J'ai cherché avant, mais je ne pouvais pas le trouver! Merci beaucoup! – koda

Répondre

32

Comme d'iOS 4.0, le SDK iOS inclut le CGImageSource... functions (dans le cadre ImageIO). C'est une API très flexible pour interroger les métadonnées sans charger l'image dans la mémoire. Obtenir les dimensions en pixels d'une image devrait fonctionner comme ceci (assurez-vous d'inclure le ImageIO.framework dans votre cible):

#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); 

(adapté de « Programmation avec Quartz » par Gelphman et Laden, la liste 9.5, à la page 228)

+2

Pourquoi utiliser 'CGImageSourceCopyPropertiesAtIndex' au lieu de simplement' CGImageSourceCopyProperties'? – jcm

+3

Il est très important de passer 'kCFNumberCGFloatType' à la place de' kCFNumberFloatType' quand on appelle CFNumberGetValue() puisque les variables 'width' et' height' sont déclarées comme 'CGFloat'. Le code ci-dessus fonctionnera sur les systèmes 32 bits mais les valeurs contiendront des erreurs sur les systèmes 64 bits. – fjoachim

+0

@fjoachim: Merci, corrigé. –

3

Swift 3 version de la réponse:

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