2010-11-12 21 views
18

Bildiğiniz gibi iphone yönergeleri 1024x1024'ten daha büyük olan uiimages yüklemelerini engelliyor.Bellekte yükleme yapmadan UIImage özelliklerine erişme image

Yüklemek zorunda kalacağım görüntülerin boyutu değişiyor ve yüklemek üzere olduğum görüntünün boyutunu kontrol etmek istiyorum; Bununla birlikte, uiimage'in .size özelliğini kullanmak, görüntünün doldurulmasını gerektirir ... bu da kaçınmaya çalıştığım şeydir.

Gerekçelendirmemde yanlış bir şey mi var, yoksa bunun bir çözümü var mı?

, iOS SDK (ImageIO çerçevesinde) CGImageSource... functions kapsamaktadır iOS 4.0 itibariyle sen iyi

+1

Bu iyi bir soru. Android bunu yapmanın bir yolunu sunuyor, ancak bir iOS çözümünü bilemiyorum. DÜZENLEME: Bu daha önce sorulmuştur. http://stackoverflow.com/questions/1551300/get-size-of-image-without-loading-in-to-memory – Justin

+0

Daha önce aradım ama bulamadım! çok teşekkürler! – koda

cevap

32

teşekkür ederim. Resmi belleğe yüklemeden meta verileri sorgulamak için çok esnek bir API. , Sayfa 228 9.5 listeleme, Gelphman ve Ladin tarafından "Kuvars ile programlama" dan uyarlanan

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

(: Bu gibi çalışması gereken bir görüntünün piksel boyutları alma (Kendi hedef ImageIO.framework eklemeyi unutmayın) cevap)

+2

Neden sadece 'CGImageSourceCopyProperties' yerine CGImageSourceCopyPropertiesAtIndex'? – jcm

+3

CFNumberGetValue() öğesini çağırırken 'kCFNumberFloatType 'yerine' kCFNumberCGFloatType' değerini geçmek için 'width' ve 'height 'değişkenleri' CGFloat 'olarak bildirildiğinden çok önemlidir. Yukarıdaki kod, 32 bit sistemlerde çalışacaktır, ancak değerler 64 bit sistemlerde çöp içerecektir. – fjoachim

+0

@fjoachim: Teşekkürler, düzeltildi. –

3

Swift 3 sürümü:

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