Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 通过文件URL远程获取图像文件维度_Ios_Objective C_Image_Uiimage_Dropbox Api - Fatal编程技术网

Ios 通过文件URL远程获取图像文件维度

Ios 通过文件URL远程获取图像文件维度,ios,objective-c,image,uiimage,dropbox-api,Ios,Objective C,Image,Uiimage,Dropbox Api,我正在使用Dropbox Core API,在寻找获取图像文件的方法时,我陷入了困境。我在设备上检索缩略图,但我需要知道图像的宽度和高度,以便对其进行修改 我绝对不想在手机上下载整个文件来检查它的尺寸。你有没有想过要耍什么花招。元数据中唯一的东西就是文件大小,这在我的例子中是非常无用的 非常感谢。我找到了答案。我使用UIImage类别,而不是通过URL下载部分文件。一旦获得足够的数据来定义大小,它就会停止下载 我做了一些测试,它下载了大约30KB来获取图片的尺寸,不管文件大小是300KB还是10

我正在使用Dropbox Core API,在寻找获取图像文件的方法时,我陷入了困境。我在设备上检索缩略图,但我需要知道图像的宽度和高度,以便对其进行修改

我绝对不想在手机上下载整个文件来检查它的尺寸。你有没有想过要耍什么花招。元数据中唯一的东西就是文件大小,这在我的例子中是非常无用的


非常感谢。

我找到了答案。我使用UIImage类别,而不是通过URL下载部分文件。一旦获得足够的数据来定义大小,它就会停止下载

我做了一些测试,它下载了大约30KB来获取图片的尺寸,不管文件大小是300KB还是10MB,这都非常快

它可以用于任何图像文件,而不仅仅是Dropbox API

以下是类别的标题:

#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>`

#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[偏移量+1]==0xC7||
cString[偏移量+1]==0xC9||
cString[offset+1]==0xCA||
cString[偏移量+1]==0xCB||
cString[offset+1]==0xCD||
cString[offset+1]==0xCE||
cString[偏移量+1]==0xCF){
dword宽度=0,高度=0;