Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈。 这篇文章主要学习如何在IOS程序中打开照相机与本地相册并且选择一张图片。还是老样子MOMO写了一个简单的测试程序,如下图所示 在本地相册中选择一张图片后,我们将他拷贝至沙盒当中,在客户端中将它的缩略图放在按钮旁边,这个结构其实和新浪微薄中选择图片后的效果一样。最终点击发送将按钮将图片2进制图片上传服务器。
下面我们仔细学习具体的细节。创建一个空的IOS项目,接着在创建一个ViewController。
AppDelegate.h 应用的代理类 这个没什么好说的就是直接打开刚刚创建的新ViewController。
#import <UIKit/UIKit.h>
#import "TestViewController.h"
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navController;
@property (strong, nonatomic) UIViewController *viewController;
@end
AppDelegate.m 在这里就是打开我们创建的TestViewController
#import "AppDelegate.h"
@implementation AppDelegate
@synthesize window = _window;
@synthesize navController;
@synthesize viewController;
- (void)dealloc
{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.backgroundColor = [UIColor whiteColor];
self.viewController = [[TestViewController alloc]init];
self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navController.view];
[self.window makeKeyAndVisible];
return YES;
}
@end
TestViewController.h 注意这里面引入了很多代理类。
#import <UIKit/UIKit.h>
@interface TestViewController : UIViewController<UITextViewDelegate,UIActionSheetDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>
{
//输入框
UITextView *_textEditor;
//下拉菜单
UIActionSheet *myActionSheet;
//图片2进制路径
NSString* filePath;
}
@end
TestViewController.m 请大家仔细看这个类, 所有的东西都写在了这里哈。
#import "TestViewController.h"
@interface TestViewController ()
@end
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//导航栏标题
self.navigationItem.title = @"雨松MOMO输入框";
//导航栏按钮
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithTitle: @"发送"
style: UIBarButtonItemStyleDone
target: self
action: @selector(sendInfo)] autorelease];
//输入框显示区域
_textEditor = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 320, 100)];
//设置它的代理
_textEditor.delegate = self;
_textEditor.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_textEditor.keyboardType = UIKeyboardTypeDefault;
_textEditor.font = [UIFont systemFontOfSize:20];
_textEditor.text = @"请输入内容";
//默认软键盘是在触摸区域后才会打开
//这里表示进入当前ViewController直接打开软键盘
[_textEditor becomeFirstResponder];
//把输入框加在视图中
[self.view addSubview:_textEditor];
//下方的图片按钮 点击后呼出菜单 打开摄像机 查找本地相册
UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"camera" ofType:@"png"]];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 120, image.size.width, image.size.height);
[button setImage:image forState:UIControlStateNormal];
[button addTarget:self action:@selector(openMenu) forControlEvents:UIControlEventTouchUpInside];
//把它也加在视图当中
[self.view addSubview:button];
}
-(void)openMenu
{
//在这里呼出下方菜单按钮项
myActionSheet = [[UIActionSheet alloc]
initWithTitle:nil
delegate:self
cancelButtonTitle:@"取消"
destructiveButtonTitle:nil
otherButtonTitles: @"打开照相机", @"从手机相册获取",nil];
[myActionSheet showInView:self.view];
[myActionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
//呼出的菜单按钮点击后的响应
if (buttonIndex == myActionSheet.cancelButtonIndex)
{
NSLog(@"取消");
}
switch (buttonIndex)
{
case 0: //打开照相机拍照
[self takePhoto];
break;
case 1: //打开本地相册
[self LocalPhoto];
break;
}
}
//开始拍照
-(void)takePhoto
{
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//设置拍照后的图片可被编辑
picker.allowsEditing = YES;
picker.sourceType = sourceType;
[picker release];
[self presentModalViewController:picker animated:YES];
}else
{
NSLog(@"模拟其中无法打开照相机,请在真机中使用");
}
}
//打开本地相册
-(void)LocalPhoto
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.delegate = self;
//设置选择后的图片可被编辑
picker.allowsEditing = YES;
[self presentModalViewController:picker animated:YES];
[picker release];
}
//当选择一张图片后进入这里
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
//当选择的类型是图片
if ([type isEqualToString:@"public.image"])
{
//先把图片转成NSData
UIImage* image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
NSData *data;
if (UIImagePNGRepresentation(image) == nil)
{
data = UIImageJPEGRepresentation(image, 1.0);
}
else
{
data = UIImagePNGRepresentation(image);
}
//图片保存的路径
//这里将图片放在沙盒的documents文件夹中
NSString * DocumentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
//文件管理器
NSFileManager *fileManager = [NSFileManager defaultManager];
//把刚刚图片转换的data对象拷贝至沙盒中 并保存为image.png
[fileManager createDirectoryAtPath:DocumentsPath withIntermediateDirectories:YES attributes:nil error:nil];
[fileManager createFileAtPath:[DocumentsPath stringByAppendingString:@"/image.png"] contents:data attributes:nil];
//得到选择后沙盒中图片的完整路径
filePath = [[NSString alloc]initWithFormat:@"%@%@",DocumentsPath, @"/image.png"];
//关闭相册界面
[picker dismissModalViewControllerAnimated:YES];
//创建一个选择后图片的小图标放在下方
//类似微薄选择图后的效果
UIImageView *smallimage = [[[UIImageView alloc] initWithFrame:
CGRectMake(50, 120, 40, 40)] autorelease];
smallimage.image = image;
//加在视图中
[self.view addSubview:smallimage];
}
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
NSLog(@"您取消了选择图片");
[picker dismissModalViewControllerAnimated:YES];
}
-(void)sendInfo
{
NSLog(@"图片的路径是:%@", filePath);
NSLog(@"您输入框中的内容是:%@", _textEditor.text);
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end
如下图所示,打开下拉菜单按钮开始选择打开相机 或者 打开本地相册。模拟器中是无法打开照相机的的,切记。
如下图所示,这里就是我本地的相册啦,里面保存了几张图片,选择一张即可。
我在这里再说说图片上传, 图片上传我们采用的是2进制ASIHTTPRequest 来完成的。
发送请求
NSString *server_base = [NSString stringWithFormat:@"%@/users/uploadResource.json", _server];
ASINetworkQueue *queue = [[ASINetworkQueue alloc] init];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:server_base]];
[ASIHTTPRequest setShouldUpdateNetworkActivityIndicator: NO];
[request setDelegate :self];
[request setDidFinishSelector:@selector(sendCommentSucc:)];
[request setDidFailSelector:@selector(sendCommentFail:)];
// res 就是 需要上传图片文件的路径
[request setFile:res forKey:@"res"];
[queue addOperation:request];
[queue go];
最后是文本的源码,雨松MOMO祝大家学习愉快,不早了,我也得睡觉啦,1点多了。。。
下载地址:http://vdisk.weibo.com/s/accm9
- 本文固定链接: https://www.xuanyusong.com/archives/1493
- 转载请注明: 雨松MOMO于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!




松哥,请问我的Editor Settings—Version Control—Mode中的Asset Server为什么是灰色的,少安装了什么
想你请教个问题, 将图片选择好后,保存到沙盒的过程十分缓慢,还有从沙盒中再把图片读取出现来时的过程也很慢,请问有没有什么方式可以让这个过程快些。 我是个改变了图片的压缩比例,但是没有什么明显效果。
感谢,现在是2015.09.28.。。。。。。。。O(∩_∩)O哈哈~
用了你的方法拍照完成后还是会退出程序啊
打开相机拍照确实存在问题,程序会cresh,用了你的这段代码就好了.
能发一个单独上传图片demo吗 这个问题让我头疼好久了 ASIHTTPRequest 这个引用怎么弄都是报错
这个过程实际没有截取图片。。怎么截图?就是截取一张图片的一部分
同问,截取图片无效,实际得到的还是原图。
照片上传 服务端能不能贴一下!
非常感谢。但是该工程在ipad中调用相机好像会蹦掉,在网上查了把相机的那一块改了下-(void)takePhoto{ UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera; if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) { UIImagePickerController *pickerCammer = [[UIImagePickerController alloc] init]; if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { pickerCammer.sourceType = UIImagePickerControllerSourceTypeCamera; pickerCammer.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:pickerCammer.sourceType]; pickerCammer.delegate=self; pickerCammer.allowsEditing = YES; } [self presentModalViewController:pickerCammer animated:YES]; [pickerCammer release]; }else { NSLog(@”模拟其中无法打开照相机,请在真机中使用”); } }就可以了,但是momo能不能花点时间把ipad中的图片截取写一下啊,我对xcode不是很熟悉!要是能把图片传回unity工程中使用最好了!!!
模拟器中为什么打不开照相机?
好像有几处没release
可能吧 我没注意 呵呵。。
改用ARC了?
没用。。
这个demo不工具检测有内存泄露问题。。在delegate里?
你好,我想请问一下,为什么用这段代码打开iPad相册会崩溃? 而且没有错误信息……
不会吧 你是IO6系统?? 是不是内存溢出了?
是iOS5的,不过我上次好像看漏了,有条错误信息,是说UIImagePickerController这个在iPad上必须用UIPopoverController来承载,要不就悲剧了。
另外,我测试发现一个相机问题,相机拍完照,选择了图片之后,回调到我的view中,第一次都没有问题,但是多选择几次经常会出现程序异常退出的问题,本地相册选择图片就没有这样的问题,非常奇怪
我怀疑这是IOS6的问题,
我感觉应该是内存不足的问题,图片我没有做任何微缩处理,发了几次就挂掉了,看来图片的加载内存处理比较重要
我测试了一下,UIImagePickerController回调好像没有起作用,选择本地相册之后,没有回调
你没有加代理吧。。
现在可以了,忘记回调了。
请教下、进入相册后 的 navigationController 的标题能改中文吗?
可以的。。
你好,请问有没有选取视频上传的demo?
你好,请教一个问题,我怎么才能在unity3d里调用iphone照片库和照相功能,自己试了n久都不成功,看了你的文章收获特别大,谢谢
调用iPhone的话 其实和Android差不多。。都是传递消息。
还是没成功,初学者。谢谢。
怎么在静态方法里添加视图
MOMO人很好啊,我想请问下这段上传图片的代码可以用么,我现在正在纠结这个,刚才用你的代码试了试,还是失败了,已经试过很多,都是用的ASIHTTPRequest这个框架,[request setDidFinishSelector:@selector(sendCommentSucc:)]; 这个方法已经执行完了,但是服务器没有显示图片,不知道自己错在哪了,MOMO能不能指点一二
可以用的,我就是按照这个方法上传成功的, 我们的服务器是用rubby on rails 写的
请教下,服务器用php写的话,用这种方法可以不,这个跟服务器用什么语言写的有关系么
应该可以吧, 不过我是成功了,不知道为什么你不成功