iOS实现视频和图片的上传

关于iOS如何实现视频和图片的上传, 我们先理清下思路

思路:

#1. 如何获取图片?

#2. 如何获取视频?

#3. 如何把图片存到缓存路径中?

#4. 如何把视频存到缓存路径中?

#5. 如何上传?

接下来, 我们按照上面的思路一步一步实现

首先我们新建一个类, 用来储存每一个要上传的文件uploadModel.h

#import <Foundation/Foundation.h>

@interface uploadModel : NSObject

@property (nonatomic, strong) NSString *path;
@property (nonatomic, strong) NSString *type;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) BOOL      isUploaded;

@end

#1. 如何获取图片?

从相册选择 或者 拍照,

这部分可以用UIImagePickerController来实现

代码如下:

- (void)actionPhoto {

    UIAlertController *alertController  =     [UIAlertController alertControllerWithTitle:@""
                                        message:@"上传照片"
                                 preferredStyle:UIAlertControllerStyleActionSheet];

    UIAlertAction *photoAction  =     [UIAlertAction actionWithTitle:@"从相册选择"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"从相册选择");
                               self.imagePicker.sourceType    = UIImagePickerControllerSourceTypePhotoLibrary;
                               self.imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
                               self.imagePicker.allowsEditing = YES;

                               [self presentViewController:self.imagePicker
                                                  animated:YES
                                                completion:nil];

                           }];

    UIAlertAction *cameraAction =     [UIAlertAction actionWithTitle:@"拍照"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"拍照");
                               if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

                                   self.imagePicker.sourceType        = UIImagePickerControllerSourceTypeCamera;
                                   self.imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
                                   self.imagePicker.cameraDevice      = UIImagePickerControllerCameraDeviceRear;
                                   self.imagePicker.allowsEditing     = YES;

                                   [self presentViewController:self.imagePicker
                                                      animated:YES
                                                    completion:nil];
                               }
                           }];

    UIAlertAction *cancelAction =     [UIAlertAction actionWithTitle:@"取消"
                             style:UIAlertActionStyleCancel
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"取消");
                           }];

    [alertController addAction:photoAction];
    [alertController addAction:cameraAction];
    [alertController addAction:cancelAction];

    [self presentViewController:alertController animated:YES completion:nil];
}

#2. 如果获取视频?

从相册选择 或者 拍摄

这部分也可以用UIImagePickerController来实现

代码:

- (void)actionVideo {

    UIAlertController *alertController =     [UIAlertController alertControllerWithTitle:@""
                                        message:@"上传视频"
                                 preferredStyle:UIAlertControllerStyleActionSheet];

    UIAlertAction *photoAction =     [UIAlertAction actionWithTitle:@"从视频库选择"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"从视频库选择");
                               self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
                               self.imagePicker.mediaTypes = @[(NSString *)kUTTypeMovie];
                               self.imagePicker.allowsEditing = NO;

                               [self presentViewController:self.imagePicker animated:YES completion:nil];
                           }];

    UIAlertAction *cameraAction =     [UIAlertAction actionWithTitle:@"录像"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"录像");
                               self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
                               self.imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
                               self.imagePicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
                               self.imagePicker.videoQuality = UIImagePickerControllerQualityType640x480;
                               self.imagePicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
                               self.imagePicker.allowsEditing = YES;

                               [self presentViewController:self.imagePicker animated:YES completion:nil];
                           }];

    UIAlertAction *cancelAction =     [UIAlertAction actionWithTitle:@"取消"
                             style:UIAlertActionStyleCancel
                           handler:^(UIAlertAction * _Nonnull action) {

                               NSLog(@"取消");
                           }];

    [alertController addAction:photoAction];
    [alertController addAction:cameraAction];
    [alertController addAction:cancelAction];

    [self presentViewController:alertController animated:YES completion:nil];
}

#3, 关于缓存, 如何把照片存入缓存目录?

这部分我们先考虑缓存目录, 一般存在Document 或者 Temp里面

我们给图片和视频各创建一个缓存目录:

#define PHOTOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"photoCache"]
#define VIDEOCACHEPATH [NSTemporaryDirectory() stringByAppendingPathComponent:@"videoCache"]

把UIImage存入缓存的方法:

//将Image保存到缓存路径中
- (void)saveImage:(UIImage *)image toCachePath:(NSString *)path {

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:PHOTOCACHEPATH]) {

        NSLog(@"路径不存在, 创建路径");
        [fileManager createDirectoryAtPath:PHOTOCACHEPATH
               withIntermediateDirectories:YES
                                attributes:nil
                                     error:nil];
    } else {

        NSLog(@"路径存在");
    }

    //[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
    [UIImageJPEGRepresentation(image, 1) writeToFile:path atomically:YES];
}

4. 如何把视频存入缓存?

把视频存入缓存的方法:

//将视频保存到缓存路径中
- (void)saveVideoFromPath:(NSString *)videoPath toCachePath:(NSString *)path {

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:VIDEOCACHEPATH]) {

        NSLog(@"路径不存在, 创建路径");
        [fileManager createDirectoryAtPath:VIDEOCACHEPATH
               withIntermediateDirectories:YES
                                attributes:nil
                                     error:nil];
    } else {

        NSLog(@"路径存在");
    }

    NSError *error;
    [fileManager copyItemAtPath:videoPath toPath:path error:&error];
    if (error) {

        NSLog(@"文件保存到缓存失败");
    }
}

从缓存获取图片的方法:

//从缓存路径获取照片
- (UIImage *)getImageFromPath:(NSString *)path {

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {

        return [UIImage imageWithContentsOfFile:path];
    }

    return nil;
}

上传图片和视频的时候我们一般会利用当前时间给文件命名, 方法如下

//以当前时间合成图片名称
- (NSString *)getImageNameBaseCurrentTime {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];

    return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".JPG"];
}

//以当前时间合成视频名称
- (NSString *)getVideoNameBaseCurrentTime {

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH-mm-ss"];

    return [[dateFormatter stringFromDate:[NSDate date]] stringByAppendingString:@".MOV"];
}

有时候需要获取视频的第一帧作为显示, 方法如下:

//获取视频的第一帧截图, 返回UIImage
//需要导入AVFoundation.h
- (UIImage*) getVideoPreViewImageWithPath:(NSURL *)videoPath
{
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoPath options:nil];

    AVAssetImageGenerator *gen         = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    gen.appliesPreferredTrackTransform = YES;

    CMTime time      = CMTimeMakeWithSeconds(0.0, 600);
    NSError *error   = nil;

    CMTime actualTime;
    CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
    UIImage *img     = [[UIImage alloc] initWithCGImage:image];

    return img;
}

5. 如何上传?

下面就是上传方法:

我把服务器地址xx掉了, 大家可以改为自己的

//上传图片和视频
- (void)uploadImageAndMovieBaseModel:(uploadModel *)model {

    //获取文件的后缀名
    NSString *extension = [model.name componentsSeparatedByString:@"."].lastObject;

    //设置mimeType
    NSString *mimeType;
    if ([model.type isEqualToString:@"image"]) {

        mimeType = [NSString stringWithFormat:@"image/%@", extension];
    } else {

        mimeType = [NSString stringWithFormat:@"video/%@", extension];
    }

    //创建AFHTTPSessionManager
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    //设置响应文件类型为JSON类型
    manager.responseSerializer    = [AFJSONResponseSerializer serializer];

    //初始化requestSerializer
    manager.requestSerializer     = [AFHTTPRequestSerializer serializer];

    manager.responseSerializer.acceptableContentTypes = nil;

    //设置timeout
    [manager.requestSerializer setTimeoutInterval:20.0];

    //设置请求头类型
    [manager.requestSerializer setValue:@"form/data" forHTTPHeaderField:@"Content-Type"];

    //设置请求头, 授权码
    [manager.requestSerializer setValue:@"YgAhCMxEehT4N/DmhKkA/M0npN3KO0X8PMrNl17+hogw944GDGpzvypteMemdWb9nlzz7mk1jBa/0fpOtxeZUA==" forHTTPHeaderField:@"Authentication"];

    //上传服务器接口
    NSString *url = [NSString stringWithFormat:@"http://xxxxx.xxxx.xxx.xx.x"];

    //开始上传
    [manager POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

        NSError *error;
        BOOL success = [formData appendPartWithFileURL:[NSURL fileURLWithPath:model.path] name:model.name fileName:model.name mimeType:mimeType error:&error];
        if (!success) {

            NSLog(@"appendPartWithFileURL error: %@", error);
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {

        NSLog(@"上传进度: %f", uploadProgress.fractionCompleted);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

        NSLog(@"成功返回: %@", responseObject);
        model.isUploaded = YES;
        [self.uploadedArray addObject:model];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

        NSLog(@"上传失败: %@", error);
        model.isUploaded = NO;
    }];
}

这里有事先创建两个可变数组uploadArray, uploadedArray, 一个存放准要上传的内容, 一个存放上传完的内容

在准备上传后做什么操作, 可以检查两个数组的数量是否相等

最后是UIImagePickerController的协议方法

#pragma mark - UIImagePickerDelegate methods

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {

    [picker dismissViewControllerAnimated:YES completion:nil];

    //获取用户选择或拍摄的是照片还是视频
    NSString *mediaType = info[UIImagePickerControllerMediaType];

    if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {

        //获取编辑后的照片
        NSLog(@"获取编辑后的好片");
        UIImage *tempImage = info[UIImagePickerControllerEditedImage];

        //将照片存入相册
        if (tempImage) {

            if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {

                //将照片存入相册
                NSLog(@"将照片存入相册");
                UIImageWriteToSavedPhotosAlbum(tempImage, self, nil, nil);
            }

            //获取图片名称
            NSLog(@"获取图片名称");
            NSString *imageName = [self getImageNameBaseCurrentTime];
            NSLog(@"图片名称: %@", imageName);

            //将图片存入缓存
            NSLog(@"将图片写入缓存");
            [self saveImage:tempImage
                toCachePath:[PHOTOCACHEPATH stringByAppendingPathComponent:imageName]];

            //创建uploadModel
            NSLog(@"创建model");
            uploadModel *model = [[uploadModel alloc] init];

            model.path       = [PHOTOCACHEPATH stringByAppendingPathComponent:imageName];
            model.name       = imageName;
            model.type       = @"image";
            model.isUploaded = NO;

            //将模型存入待上传数组
            NSLog(@"将Model存入待上传数组");
            [self.uploadArray addObject:model];

        }
    }

    else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {

        if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {

            //如果是拍摄的视频, 则把视频保存在系统多媒体库中
            NSLog(@"video path: %@", info[UIImagePickerControllerMediaURL]);

            ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
            [library writeVideoAtPathToSavedPhotosAlbum:info[UIImagePickerControllerMediaURL] completionBlock:^(NSURL *assetURL, NSError *error) {

                if (!error) {

                    NSLog(@"视频保存成功");
                } else {

                    NSLog(@"视频保存失败");
                }
            }];
        }

        //生成视频名称
        NSString *mediaName = [self getVideoNameBaseCurrentTime];
        NSLog(@"mediaName: %@", mediaName);

        //将视频存入缓存
        NSLog(@"将视频存入缓存");
        [self saveVideoFromPath:info[UIImagePickerControllerMediaURL] toCachePath:[VIDEOCACHEPATH stringByAppendingPathComponent:mediaName]];

        //创建uploadmodel
        uploadModel *model = [[uploadModel alloc] init];

        model.path       = [VIDEOCACHEPATH stringByAppendingPathComponent:mediaName];
        model.name       = mediaName;
        model.type       = @"moive";
        model.isUploaded = NO;

        //将model存入待上传数组
        [self.uploadArray addObject:model];
    }

    //[picker dismissViewControllerAnimated:YES completion:nil];

}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

    [picker dismissViewControllerAnimated:YES completion:nil];
}
时间: 2024-10-21 23:01:13

iOS实现视频和图片的上传的相关文章

ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结

相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直接从应用程序访问,只能通过终端用户去选择和使用相册图片 应用程序包 应用程序包可能会将图像与可执行程序.Info.plist文件和其他资源一同存储.我们可以通过本地文件路径来读取这些基于包的图像并在应用程序中显示它们. 沙盒 借助沙盒,我们可以把图片存储到Documents.Library.tmp文

Html5+asp.net mvc 图片压缩上传

在做图片上传时,大图片如果没有压缩直接上传时间会非常长,因为有的图片太大,传到服务器上再压缩太慢了,而且损耗流量. 思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法得到base64字符串来实现压缩. 废话不多少不多说直接看代码: 本次测试使用了 zepto.min.js 插件,更新版本的下载请点击这里 主要js代码: //图片压缩处理 ; (function () { /** * 加载的时候进行抽样检测 * 在iOS中,大于2M的图片会抽样渲染 */ func

iOS视频压缩存储至本地并上传至服务器-b

最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视频原封不动地从相册拿出来放到沙盒路径下,目的是拿到视频的NSData以便上传 这里我传了一个URL,这个URL有点特别,是相册文件URL,所以我说过只针对相册视频进行处理 //将原始视频的URL转化为NSData数据,写入沙盒     + (void)videoWithUrl:(NSString *

iOS视频压缩存储至本地并上传至服务器

最近做了一个项目,我把其中的核心功能拿出来和大家分享一下,重点还是自己梳理一下. 这里关于视频转码存储我整理了两个方法,这两个方法都是针对相册内视频进行处理的. 1.该方法没有对视频进行压缩,只是将视频原封不动地从相册拿出来放到沙盒路径下,目的是拿到视频的NSData以便上传 这里我传了一个URL,这个URL有点特别,是相册文件URL,所以我说过只针对相册视频进行处理 //将原始视频的URL转化为NSData数据,写入沙盒 + (void)videoWithUrl:(NSString *)url

iOS开发网络篇—文件的上传

iOS开发网络篇—文件的上传 说明:文件上传使用的时POST请求,通常把要上传的数据保存在请求体中.本文介绍如何不借助第三方框架实现iOS开发中得文件上传. 由于过程较为复杂,因此本文只贴出部分关键代码. 主控制器的关键代码: YYViewController.m 1 #import "YYViewController.h" 2 3 #define YYEncode(str) [str dataUsingEncoding:NSUTF8StringEncoding] 4 5 @inter

onethink框架 编辑器图片没有上传权限

昨天遇到了一个有点蛋疼的问题,创建了一个用户,但是在添加数据的时候,发现编辑器中的图片上传不能使用老是提示下图的那种提示: 然后自己一直在想,怎么编辑器还要图片上传权限呢,淡淡的忧伤啊.然后自己琢磨了一会,发现自己解决不了.立马到Q群中询问,一问,还真的搞定了.原来是要设置权限,不过这个权限是框架数据中早就有了,我们只需要勾选上就可以了.当然了,我这种情况只适用于直接在框架demo上扩展使用的项目,如果完全是自己编写的,那就要看你们各自的构建是咋样的啦.废话不多说,上图:这下子清净了,搞定,再也

MVC 4 图片的上传及显示

首先我们看一下如何上传: 1. view 上传页面: 1: @using (Html.BeginForm("Create", "Achievement", FormMethod.Post, new { enctype = "multipart/form-data" })) 2: { 3: <div class="editor-label"> 4: @Html.LabelFor(model => model.P

Asp.Net 自定义控件实现图片的上传,浏览,删除功能

4月的时候公司比较闲,就想着自己做点东西,其实主要是为了更加熟悉.Net,毕竟接触的时间不长,趁着有时间想提高提高.不过当我做到图片上传这个功能的时候,就有些停滞不前了,连续写了两天也达不到自己想要的标准.后来公司来活,然后就没有然后了,然而做事总不能半途而废吧~时隔一个多月,趁着这个周末,我再次拾起了这个项目,而首要工作就是攻破这个图片上传控件. 下面说说我的标准是什么子的吧~ 1.最多可以上传三张图片,超过三张有提示. 2.点击图片小图,有图片放大功能,再次点击,图片恢复原来尺寸. 3.在图

SSM配置Ueditor实现图片的上传&lt;一&gt;

最近想学点新的东西,于是琢磨着用SSM整合Ueditor来实现图片的上传!至于为什么选Ueditor,道理你懂得啦!百度开发的而且开源,能自定义自己想要的内容,版本更新什么的也比较勤快!接下来我准备记录下探索的过程! 1.下载 点击跳转到Ueditor下载界面 你可以到上面的地址下载Ueditor插件,选择UTF-8编码的Jsp版本. 2.构建工程 新建一个Maven工程,首先把ssm框架的基本的东西搭建好,如果你不清楚ssm基本框架,我博客里面有详细的搭建过程可以参考!在这我就直接上图了! 3