2010-11-12 8 views
18

Come sapete, le linee guida per l'iphone scoraggiano il caricamento di immagini superiori a 1024x1024.accesso alle proprietà UIImage senza caricare in memoria l'immagine

La dimensione delle immagini che avrei dovuto caricare varia e vorrei verificare la dimensione dell'immagine che sto per caricare; tuttavia, l'uso della proprietà .size di uiimage richiede che l'immagine sia laosa ... che è esattamente quello che sto cercando di evitare.

C'è qualcosa di sbagliato nel mio ragionamento o c'è una soluzione a questo?

grazie a tutti voi

+1

Questa è una buona domanda. Android fornisce un mezzo per farlo, ma non conosco una soluzione iOS. EDIT: questo è stato chiesto prima. http://stackoverflow.com/questions/1551300/get-size-of-image-without-loading-in-memory – Justin

+0

ho cercato prima, ma non riuscivo a trovarlo! grazie molto! – koda

risposta

32

Come di iOS 4.0, iOS SDK include il CGImageSource... functions (nel quadro ImageIO). È un'API molto flessibile per interrogare i metadati senza caricare l'immagine nella memoria. Ottenere le dimensioni in pixel di un'immagine dovrebbe funzionare come questo (assicurarsi di includere l'ImageIO.framework nel vostro 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); 

(tratto da "Programmazione con Quartz" di Gelphman e Laden, elencando 9.5, pagina 228)

+2

Perché utilizzare 'CGImageSourceCopyPropertiesAtIndex' anziché solo' CGImageSourceCopyProperties'? – jcm

+3

È molto importante passare 'kCFNumberCGFloatType' invece di' kCFNumberFloatType' quando si chiama CFNumberGetValue() poiché le variabili 'width' e' height' sono dichiarate come 'CGFloat'. Il codice sopra funzionerà su sistemi a 32 bit, ma i valori conterranno spazzatura su sistemi a 64 bit. – fjoachim

+0

@fjoachim: Grazie, risolto. –

3

Swift 3 versione della risposta:

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