2011-08-23 29 views
5

Sử dụng Obj-c/Cocoa-touch, tôi đang cố gắng lấy kích thước hình ảnh của danh sách hình ảnh nhưng tôi không muốn tải xuống chúng. Có cách nào dễ dàng để làm điều đó không? Tôi đã tìm thấy một số giải pháp bằng các ngôn ngữ khác như this SO question nhưng tôi đang tìm cách dễ dàng hơn.Kích thước hình ảnh từ xa mà không cần tải xuống

Cảm ơn

+0

kích thước hình ảnh (chiều rộng/chiều cao)? hoặc kích thước tệp hình ảnh? – progrmr

+0

Kích thước hình ảnh – jonzz

Trả lời

0

Nếu bạn muốn nhận được chỉ là kích thước của tập tin hình ảnh mà bạn có thể sử dụng một NSURLConnection yêu cầu chỉ tiêu đề từ máy chủ HTTP (mà không cần tải tập tin hình ảnh) và sau đó trích xuất các Content-Length: từ tiêu đề để nhận kích thước tệp. Sử dụng phương thức expectedContentLength trong lớp NSURLResponse, xem the doc để biết thêm chi tiết. Nó vẫn không dễ dàng.

+0

Để làm điều đó tôi có thể sử dụng ASIHTTPRequest. Tôi có nghĩa là kích thước hình ảnh và không kích thước, xin lỗi – jonzz

7

Đây là danh mục UII mà tôi sử dụng cho việc này. Nó được dựa trên fastimage. Một cảnh báo chính là NSURLConnectionDelegate được đặt thành chính NSURL và điều này có thể gây ra xung đột trong các tình huống nhất định. Điều này chưa hoàn thành (ví dụ: URL của tệp bị bỏ qua ...) nhưng bạn có thể thấy nó đang đi đâu.

Tiêu đề:

#import <UIKit/UIKit.h> 

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

@interface UIImage (RemoteSize) 

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

@end 

Nguồn:

#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

Tuyệt vời! Cảm ơn bạn rất nhiều ! – BoilingLime

Các vấn đề liên quan