2014-05-12 4 views
3

Dropbox Core API를 사용하고 있으며 이미지 파일 크기를 얻는 방법을 찾고있는 중 멈추어 있습니다. 기기의 미리보기 이미지를 가져옵니다. 그러나 이미지의 너비와 높이를 알고 수정해야합니다.파일 URL을 통해 이미지 파일 크기를 원격으로 가져 오기

그리고 크기를 확인하기 위해 전화로 전체 파일을 다운로드하고 싶지는 않습니다. 그 (것)들을 얻기 위하여 당신이 대략 생각하는 어떤 간계가 있는가. 필자가 메타 데이터에서 가지고있는 유일한 것은 파일 크기인데, 이는 제 경우에는별로 쓸모가 없습니다.

고마워요.

+0

까다로운 질문이지만 이미지를 다운로드하고 크기를 계산하는 것 외에는 다른 방법이 없다고 생각합니다. – satheeshwaran

+0

@satheeshwaran 해결책에 대해 흥미가 있다면 대답을 확인하십시오. 전체 파일을 다운로드하지 마십시오. 유용 할 수 있습니다. 어쨌든 고마워. – BoilingLime

답변

3

나는 내 대답을 알아 냈다. URL을 통해 파일의 다운로드 부분보다 UIImage 범주를 사용합니다. 일단 크기를 정의하기에 충분한 데이터를 얻으면 다운로드가 중지됩니다.

몇 가지 테스트를 수행했는데 파일 크기가 300kB 또는 10MB가 큰 경우 사진의 크기를 얻기 위해 약 30KB가 다운로드됩니다.

Dropbox API뿐만 아니라 모든 이미지 파일에 사용할 수 있습니다. 여기

이 카테고리의 헤더입니다 :

#import <UIKit/UIKit.h> 

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

@interface UIImage (RemoteSize) 

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

@end 

그리고 여기 소스 파일은 다음과 같습니다 Remote image size without downloading

:

#import "UIImage+RemoteSize.h" 
#import <objc/runtime.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

이미지 URL을 검색하여이 카테고리로 전달하면이 카테고리에서 이미지 크기를 가져옵니다. 멋진 사람, 좋은 구현. GitHub에 게시 할 수 있습니다. – satheeshwaran

관련 문제