gpt4 book ai didi

ios - 使用 Base64 和 JSON 上传大图像

转载 作者:可可西里 更新时间:2023-11-01 03:42:09 25 4
gpt4 key购买 nike

我正在使用此函数使用 JSON 将图像上传到服务器。为此,我首先将图像转换为 NSData,然后使用 Base64 转换为 NSString。当图像不是很大时,该方法工作正常,但当我尝试上传 2Mb 图像时,它崩溃了。

问题是即使调用了 didReceiveResponse 方法以及返回 (null)< 的 didReceiveData 方法,服务器也没有收到我的图像。起初我以为这是超时问题,但即使将其设置为 1000.0 也仍然不起作用。任何想法?感谢您的宝贵时间!

这是我当前的代码:

 - (void) imageRequest {

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.myurltouploadimage.com/services/v1/upload.json"]];

NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *path = [NSString stringWithFormat:@"%@/design%i.png",docDir, designNum];
NSLog(@"%@",path);

NSData *imageData = UIImagePNGRepresentation([UIImage imageWithContentsOfFile:path]);
[Base64 initialize];
NSString *imageString = [Base64 encode:imageData];

NSArray *keys = [NSArray arrayWithObjects:@"design",nil];
NSArray *objects = [NSArray arrayWithObjects:imageString,nil];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:kNilOptions error:&error];

[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];

[[NSURLConnection alloc] initWithRequest:request delegate:self];

NSLog(@"Image uploaded");

}

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

NSLog(@"didReceiveResponse");

}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

NSLog(@"%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);

}

最佳答案

我最终决定上传 Base64 图像,将其拆分为更小的子字符串。为此,由于我需要许多 NSURLConnections,我创建了一个名为 TagConnection 的子类,它为每个连接提供一个标记,这样它们之间就不会出现混淆。

然后我在 MyViewController 中创建了一个 TagConnection 属性,目的是从任何函数访问它。如您所见,-startAsyncLoad:withTag: 函数分配并初始化 TagConnection-connection:didReceiveData: 函数删除当我收到来自服务器的响应时。

参照-uploadImage函数,首先将图片转为字符串,然后将其切 block 放入JSON请求中。调用直到变量偏移量大于字符串长度,这意味着所有 block 都已上传。

您还可以通过每次检查服务器响应并仅在返回成功时调用-uploadImage 函数来证明每个 block 都已成功上传。

我希望这是一个有用的答案。谢谢。

TagConnection.h

@interface TagConnection : NSURLConnection {
NSString *tag;
}

@property (strong, nonatomic) NSString *tag;

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag;

@end

TagConnection.m

#import "TagConnection.h"

@implementation TagConnection

@synthesize tag;

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately tag:(NSString*)tag {
self = [super initWithRequest:request delegate:delegate startImmediately:startImmediately];

if (self) {
self.tag = tag;
}
return self;
}

- (void)dealloc {
[tag release];
[super dealloc];
}

@end

MyViewController.h

#import "TagConnection.h"

@interface MyViewController : UIViewController

@property (strong, nonatomic) TagConnection *conn;

MyViewController.m

#import "MyViewController.h"

@interface MyViewController ()

@end

@synthesize conn;

bool stopSending = NO;
int chunkNum = 1;
int offset = 0;

- (IBAction) uploadImageButton:(id)sender {

[self uploadImage];

}

- (void) startAsyncLoad:(NSMutableURLRequest *)request withTag:(NSString *)tag {

self.conn = [[[TagConnection alloc] initWithRequest:request delegate:self startImmediately:YES tag:tag] autorelease];

}

- (void) uploadImage {

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.mywebpage.com/upload.json"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1000.0];

NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *path = [NSString stringWithFormat:@"%@/design%i.png", docDir, designNum];
NSLog(@"%@",path);

NSData *imageData = UIImagePNGRepresentation([UIImage imageWithContentsOfFile:path]);
[Base64 initialize];
NSString *imageString = [Base64 encode:imageData];

NSUInteger length = [imageString length];
NSUInteger chunkSize = 1000;

NSUInteger thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset;
NSString *chunk = [imageString substringWithRange:NSMakeRange(offset, thisChunkSize)];
offset += thisChunkSize;

NSArray *keys = [NSArray arrayWithObjects:@"design",@"design_id",@"fragment_id",nil];
NSArray *objects = [NSArray arrayWithObjects:chunk,@"design_id",[NSString stringWithFormat:@"%i", chunkNum],nil];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDictionary options:kNilOptions error:&error];

[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d",[jsonData length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:jsonData];

[self startAsyncLoad:request withTag:[NSString stringWithFormat:@"tag%i",chunkNum]];

if (offset > length) {
stopSending = YES;
}

}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

NSError *error;
NSArray *responseData = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (!responseData) {
NSLog(@"Error parsing JSON: %@", error);
} else {
if (stopSending == NO) {
chunkNum++;
[self.conn cancel];
self.conn = nil;
[self uploadImage];
} else {
NSLog(@"---------Image sent---------");
}
}

}

@end

关于ios - 使用 Base64 和 JSON 上传大图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14910142/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com