2011-08-23 11 views
5

Używanie Obj-c/Cocoa-touch, Próbuję uzyskać rozmiar obrazu listy obrazów, ale nie chcę ich pobierać. Czy jest jakiś łatwy sposób to zrobić? Znalazłem rozwiązania w innych językach, takich jak this SO question, ale szukam prostszego sposobu.Zdalny rozmiar obrazu bez pobierania

Dzięki

+0

wymiary obrazu (szerokość/wysokość)? lub rozmiar pliku obrazu? – progrmr

+0

Wymiary obrazu – jonzz

Odpowiedz

0

Jeśli chcesz uzyskać tylko rozmiar pliku obrazu, można użyć NSURLConnection żądać tylko nagłówki z serwera HTTP (bez pobierania pliku obrazu), a następnie wyodrębnić Content-Length: z nagłówków, aby uzyskać rozmiar pliku. Użyj metody expectedContentLength w klasie NSURLResponse, zobacz: the doc, aby uzyskać więcej informacji. To wciąż nie jest łatwe.

+0

Aby to zrobić, mogę użyć ASIHTTPRequest. Miałem na myśli wymiary obrazu, a nie rozmiar, przepraszam – jonzz

7

Oto kategoria UIImage używam do tego. Oparty jest na fastimage. Jednym z głównych ostrzeżeń jest to, że NSURLConnectionDelegate jest ustawiony na NSURL, co może powodować konflikty w pewnych sytuacjach. To jeszcze nie jest kompletne (adresy URL plików są ignorowane na przykład ...), ale możesz zobaczyć, dokąd zmierza.

Header:

#import <UIKit/UIKit.h> 

typedef void (^UIImageSizeRequestCompleted) (NSURL* imgURL, CGSize size); 

@interface UIImage (RemoteSize) 

+ (void) requestSizeFor: (NSURL*) imgURL completion: (UIImageSizeRequestCompleted) completion; 

@end 

Źródło:

#import "UIImage+RemoteSize.h" 

#import <objc/runtime.h> 

static char *kSizeRequestDataKey = "NSURL.sizeRequestData"; 
static char *kSizeRequestTypeKey = "NSURL.sizeRequestType"; 
static char *kSizeRequestCompletionKey = "NSURL.sizeRequestCompletion"; 

typedef uint32_t dword; 

@interface NSURL (RemoteSize) 
@property (nonatomic, strong) NSMutableData* sizeRequestData; 
@property (nonatomic, strong) NSString* sizeRequestType; 
@property (nonatomic, copy) UIImageSizeRequestCompleted sizeRequestCompletion; 
@end 

@implementation NSURL (RemoteSize) 

- (void) setSizeRequestCompletion: (UIImageSizeRequestCompleted) block { 
    objc_setAssociatedObject(self, &kSizeRequestCompletionKey, block, OBJC_ASSOCIATION_COPY); 
} 

- (UIImageSizeRequestCompleted) sizeRequestCompletion { 
    return objc_getAssociatedObject(self, &kSizeRequestCompletionKey); 
} 

- (void) setSizeRequestData:(NSMutableData *)sizeRequestData { 
    objc_setAssociatedObject(self, &kSizeRequestDataKey, sizeRequestData, OBJC_ASSOCIATION_RETAIN); 
} 

- (NSMutableData*) sizeRequestData { 
    return objc_getAssociatedObject(self, &kSizeRequestDataKey); 
} 

- (void) setSizeRequestType:(NSString *)sizeRequestType { 
    objc_setAssociatedObject(self, &kSizeRequestTypeKey, sizeRequestType, OBJC_ASSOCIATION_RETAIN); 
} 

- (NSString*) sizeRequestType { 
    return objc_getAssociatedObject(self, &kSizeRequestTypeKey); 
} 

#pragma mark - NSURLConnectionDelegate 
- (void) connection: (NSURLConnection*) connection didReceiveResponse:(NSURLResponse *)response { 
    [self.sizeRequestData setLength: 0]; //Redirected => reset data 
} 

- (void) connection: (NSURLConnection*) connection didReceiveData:(NSData *)data { 
    NSMutableData* receivedData = self.sizeRequestData; 

    if(!receivedData) { 
     receivedData = [NSMutableData data]; 
     self.sizeRequestData = receivedData; 
    } 

    [receivedData appendData: data]; 

    //Parse metadata 
    const unsigned char* cString = [receivedData bytes]; 
    const NSInteger length = [receivedData length]; 

    const char pngSignature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; 
    const char bmpSignature[2] = {66, 77}; 
    const char gifSignature[2] = {71, 73}; 
    const char jpgSignature[2] = {255, 216}; 

    if(!self.sizeRequestType) { 
     if(memcmp(pngSignature, cString, 8) == 0) { 
      self.sizeRequestType = @"PNG"; 
     } 
     else if(memcmp(bmpSignature, cString, 2) == 0) { 
      self.sizeRequestType = @"BMP"; 
     } 
     else if(memcmp(jpgSignature, cString, 2) == 0) { 
      self.sizeRequestType = @"JPG"; 
     } 
     else if(memcmp(gifSignature, cString, 2) == 0) { 
      self.sizeRequestType = @"GIF"; 
     } 
    } 

    if([self.sizeRequestType isEqualToString: @"PNG"]) { 
     char type[5]; 
     int offset = 8; 

     dword chunkSize = 0; 
     int chunkSizeSize = sizeof(chunkSize); 

     if(offset+chunkSizeSize > length) 
      return; 

     memcpy(&chunkSize, cString+offset, chunkSizeSize); 
     chunkSize = OSSwapInt32(chunkSize); 
     offset += chunkSizeSize; 

     if(offset + chunkSize > length) 
      return; 

     memcpy(&type, cString+offset, 4); type[4]='\0'; 
     offset += 4; 

     if(strcmp(type, "IHDR") == 0) { //Should always be first 
      dword width = 0, height = 0; 
      memcpy(&width, cString+offset, 4); 
      offset += 4; 
      width = OSSwapInt32(width); 

      memcpy(&height, cString+offset, 4); 
      offset += 4; 
      height = OSSwapInt32(height); 

      if(self.sizeRequestCompletion) { 
       self.sizeRequestCompletion(self, CGSizeMake(width, height)); 
      } 

      self.sizeRequestCompletion = nil; 

      [connection cancel]; 
     } 
    } 
    else if([self.sizeRequestType isEqualToString: @"BMP"]) { 
     int offset = 18; 
     dword width = 0, height = 0; 
     memcpy(&width, cString+offset, 4); 
     offset += 4; 

     memcpy(&height, cString+offset, 4); 
     offset += 4; 

     if(self.sizeRequestCompletion) { 
      self.sizeRequestCompletion(self, CGSizeMake(width, height)); 
     } 

     self.sizeRequestCompletion = nil; 

     [connection cancel]; 
    } 
    else if([self.sizeRequestType isEqualToString: @"JPG"]) { 
     int offset = 4; 
     dword block_length = cString[offset]*256 + cString[offset+1]; 

     while (offset<length) { 
      offset += block_length; 

      if(offset >= length) 
       break; 
      if(cString[offset] != 0xFF) 
       break; 
      if(cString[offset+1] == 0xC0 || 
       cString[offset+1] == 0xC1 || 
       cString[offset+1] == 0xC2 || 
       cString[offset+1] == 0xC3 || 
       cString[offset+1] == 0xC5 || 
       cString[offset+1] == 0xC6 || 
       cString[offset+1] == 0xC7 || 
       cString[offset+1] == 0xC9 || 
       cString[offset+1] == 0xCA || 
       cString[offset+1] == 0xCB || 
       cString[offset+1] == 0xCD || 
       cString[offset+1] == 0xCE || 
       cString[offset+1] == 0xCF) { 

       dword width = 0, height = 0; 

       height = cString[offset+5]*256 + cString[offset+6]; 
       width = cString[offset+7]*256 + cString[offset+8]; 

       if(self.sizeRequestCompletion) { 
        self.sizeRequestCompletion(self, CGSizeMake(width, height)); 
       } 

       self.sizeRequestCompletion = nil; 

       [connection cancel]; 

      } 
      else { 
       offset += 2; 
       block_length = cString[offset]*256 + cString[offset+1]; 
      } 

     } 
    } 
    else if([self.sizeRequestType isEqualToString: @"GIF"]) { 
     int offset = 6; 
     dword width = 0, height = 0; 
     memcpy(&width, cString+offset, 2); 
     offset += 2; 

     memcpy(&height, cString+offset, 2); 
     offset += 2; 

     if(self.sizeRequestCompletion) { 
      self.sizeRequestCompletion(self, CGSizeMake(width, height)); 
     } 

     self.sizeRequestCompletion = nil; 

     [connection cancel]; 
    } 
} 

- (void) connection: (NSURLConnection*) connection didFailWithError:(NSError *)error { 
    if(self.sizeRequestCompletion) 
     self.sizeRequestCompletion(self, CGSizeZero); 
} 

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { 
    return cachedResponse; 
} 

- (void) connectionDidFinishLoading: (NSURLConnection *)connection { 
    // Basically, we failed to obtain the image size using metadata and the 
    // entire image was downloaded... 

    if(!self.sizeRequestData.length) { 
     self.sizeRequestData = nil; 
    } 
    else { 
     //Try parse to UIImage 
     UIImage* image = [UIImage imageWithData: self.sizeRequestData]; 

     if(self.sizeRequestCompletion && image) { 
      self.sizeRequestCompletion(self, [image size]); 
      return; 
     } 
    } 

    self.sizeRequestCompletion(self, CGSizeZero); 
} 

@end 

@implementation UIImage (RemoteSize) 

+ (void) requestSizeFor: (NSURL*) imgURL completion: (UIImageSizeRequestCompleted) completion { 

    if([imgURL isFileURL]) { 
     //Load from file stream 
    } 
    else { 
     imgURL.sizeRequestCompletion = completion; 

     NSURLRequest* request = [NSURLRequest requestWithURL: imgURL]; 
     NSURLConnection* conn = [NSURLConnection connectionWithRequest: request delegate: imgURL]; 
     [conn scheduleInRunLoop: [NSRunLoop mainRunLoop] forMode: NSDefaultRunLoopMode]; 
     [conn start]; 
    } 
} 

@end 
+0

Świetnie! Dziękuję bardzo ! – BoilingLime

Powiązane problemy