Ios 远程图像大小,无需下载

Ios 远程图像大小,无需下载,ios,ios4,uiimage,Ios,Ios4,Uiimage,使用Obj-c/Cocoa-touch,我试图获得图像列表的图像大小,但我不想下载它们。 有什么简单的方法吗?我在其他语言中找到了一些解决方案,如,但我正在寻找一种更简单的方法 谢谢如果您只想获取图像文件的大小,您可以使用NSUrlConnection从HTTP服务器请求标题(无需下载图像文件),然后从标题中提取内容长度:以获取文件大小。在类中使用expectedContentLength方法,有关详细信息,请参阅。这仍然不容易。这里是我用于此的UIImage类别。它是基于。一个主要警告是NSU

使用Obj-c/Cocoa-touch,我试图获得图像列表的图像大小,但我不想下载它们。 有什么简单的方法吗?我在其他语言中找到了一些解决方案,如,但我正在寻找一种更简单的方法


谢谢

如果您只想获取图像文件的大小,您可以使用NSUrlConnection从HTTP服务器请求标题(无需下载图像文件),然后从标题中提取内容长度:以获取文件大小。在类中使用expectedContentLength方法,有关详细信息,请参阅。这仍然不容易。

这里是我用于此的UIImage类别。它是基于。一个主要警告是NSURLConnectionLegate被设置为NSURL本身,这在某些情况下可能会导致冲突。这还未完成(例如忽略文件URL…),但您可以看到它的发展方向

标题:

#import <UIKit/UIKit.h>

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

@interface UIImage (RemoteSize)

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

@end
#导入
typedef void(^UIImageSizeRequestCompleted)(NSURL*imgURL,CGSize);
@接口UIImage(RemoteSize)
+(无效)请求大小用于:(NSURL*)完成图:(UIImageSizeRequestCompleted)完成图;
@结束
资料来源:

#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
#导入“UIImage+RemoteSize.h”
#进口
静态字符*kSizeRequestDataKey=“NSURL.sizeRequestData”;
静态字符*kSizeRequestTypeKey=“NSURL.sizeRequestType”;
静态字符*kSizeRequestCompletionKey=“NSURL.sizeRequestCompletion”;
类型定义uint32_t dword;
@接口NSURL(RemoteSize)
@属性(非原子,强)NSMutableData*sizeRequestData;
@属性(非原子,强)NSString*sizeRequestType;
@属性(非原子,副本)UIImageSizeRequestCompleted SizeRequestCompleted;
@结束
@实现NSURL(RemoteSize)
-(void)setSizeRequestCompletion:(UIImageSizeRequestCompleted)块{
objc_setAssociatedObject(self,&ksizereRequestCompletionKey,block,objc_ASSOCIATION_COPY);
}
-(UIImageSizeRequestCompleted)sizeRequestCompletion{
返回objc_getAssociatedObject(self和ksizereRequestCompletionKey);
}
-(void)setSizeRequestData:(NSMutableData*)sizeRequestData{
objc_setAssociatedObject(self和kSizeRequestDataKey、sizeRequestData、objc_ASSOCIATION_RETAIN);
}
-(NSMutableData*)大小请求数据{
返回objc_getAssociatedObject(self和ksizereRequestDataKey);
}
-(void)setSizeRequestType:(NSString*)sizeRequestType{
objc_setAssociatedObject(self和kSizeRequestTypeKey、sizeRequestType、objc_ASSOCIATION_RETAIN);
}
-(NSString*)sizeRequestType{
返回objc_getAssociatedObject(self和ksizereRequestTypeKey);
}
#pragma标记-NSURLConnectionLegate
-(void)连接:(NSURLConnection*)连接DidReceiverResponse:(NSURResponse*)响应{
[self.sizeRequestData setLength:0];//重定向=>重置数据
}
-(void)连接:(NSURLConnection*)连接didReceiveData:(NSData*)数据{
NSMutableData*receivedData=self.sizeRequestData;
如果(!receivedData){
接收数据=[NSMutableData];
self.sizeRequestData=receivedData;
}
[接收数据附录数据:数据];
//分析元数据
const unsigned char*cString=[receivedData bytes];
const NSInteger length=[receivedData length];
const char pngSignature[8]={137,80,78,71,13,10,26,10};
常量字符bmpSignature[2]={66,77};
常量字符签名[2]={71,73};
const char jpgSignature[2]={255,216};
如果(!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 IsequalString:@“PNG”]){
字符类型[5];
整数偏移=8;
dword chunkSize=0;
int chunkSizeSize=sizeof(chunkSize);
如果(偏移量+块大小大小>长度)
返回;
memcpy(&chunkSize,cString+offset,chunkSizeSize);
chunkSize=OSSwapInt32(chunkSize);
偏移量+=chunkSizeSize;
如果(偏移量+块大小>长度)
返回;
memcpy(&type,cString+offset,4);type[4]='\0';
偏移量+=4;
if(strcmp(type,“IHDR”)==0){//应始终位于第一位
dword宽度=0,高度=0;
memcpy(&width,cString+offset,4);
偏移量+=4;
宽度=OSSwapInt32(宽度);
memcpy(&height,cString+offset,4);
偏移量+=4;
高度=OSSwapInt32(高度);
if(self.sizeRequestCompletion){
self.sizeRequestCompletion(self,CGSizeMake(宽度、高度));
}
self.sizeRequestCompletion=nil;
[连接取消];
}
}
else if([self.sizeRequestType IsequalString:@“BMP”]){
整数偏移=18;
dword宽度=0,高度=0;
memcpy(&width,cString+offset,4);
偏移量+=4;
memcpy(&height,cString+offset,4);
偏移量+=4;
if(self.sizeRequestCompletion){
self.sizeRequestCompletion(self,CGSizeMake(宽度、高度));
}
self.sizeRequestCompletion=nil;
[连接取消];
}
else if([self.sizeRequestType IsequalString:@“JPG”]){
整数偏移=4;
dword块_长度=cString[offset]*256+cString[offset+1];
while(偏移量=长度)
打破
如果(cString[偏移量]!=0xFF)
打破
如果(cString[偏移量+1]==0xC0||
cString[偏移量+1]==0xC1||
cString[偏移量+1]==0xC2||
cString[偏移量+1]==0xC3||
cString[偏移量+1]==0xC5||
cString[偏移量+1]==0xC6||
cString[offset+1]==0x