[IOS]从相册获取图片和视频进行上传

2024-08-20 23:38

本文主要是介绍[IOS]从相册获取图片和视频进行上传,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[IOS]从相册获取图片和视频进行上传

Demo地址:http://download.csdn.net/detail/u012881779/8821955

从相册拿到图片和视频的地址,大概是这个样子,assets-library://asset/asset.MOV?id=02AEC5A4-E20B-4FAA-9B4E-A188DE467CD4&ext=MOV

这个地址无法直接用于上传,需要先将相册里的图片、视频copy到沙盒里,再使用这个新路径完成上传操作,上传完成后再清空数据即可。

图片比较好处理,可以直接在代理里面获取到数据直接转存,而视频就无法避免前面这个copy操作了。


下面的代码不全仅供参考


先导入框架:AssetsLibrary.framework


#import <AssetsLibrary/AssetsLibrary.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreMedia/CoreMedia.h>
#import <MediaPlayer/MediaPlayer.h>
#import <CommonCrypto/CommonDigest.h>
#import "GMWorkSignTableViewCell.h"
#import "ZYQAssetPickerController.h"//照片存储路径
#define KOriginalPhotoImagePath   \
[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"PhotoImages"]//视频存储路径
#define KVideoUrlPath   \
[[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"VideoURL"]@interface GMWorkSignUpViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UINavigationControllerDelegate,ZYQAssetPickerControllerDelegate,UIScrollViewDelegate,UITextFieldDelegate>@property (strong, nonatomic)NSDictionary    *valueDict;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIScrollView*scrollview;
@property (weak, nonatomic) IBOutlet UIView      *downTableView;
@property (strong, nonatomic) NSMutableArray     *infoDataArr;      //需要填写哪些资料
@property (strong, nonatomic) NSMutableArray     *leftDataArr;      //列表
@property (strong, nonatomic) NSMutableArray     *textFiledMarr;    //存储textfiled
@property (nonatomic) NSInteger uploadPicVideo;@end@implementation GMWorkSignUpViewController
//上传图片
- (IBAction)uploadPictureAction:(id)sender {_uploadPicVideo = 1;ZYQAssetPickerController *picker = [[ZYQAssetPickerController alloc] init];picker.maximumNumberOfSelection = 5;picker.assetsFilter = [ALAssetsFilter allPhotos];picker.showEmptyGroups=NO;picker.delegate=self;picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {if ([[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) {NSTimeInterval duration = [[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyDuration] doubleValue];return duration >= 5;} else {return YES;}}];[self presentViewController:picker animated:YES completion:NULL];
}//上传视频
- (IBAction)uploadVideoAction:(id)sender {_uploadPicVideo = 2;ZYQAssetPickerController *picker = [[ZYQAssetPickerController alloc] init];picker.maximumNumberOfSelection = 1;picker.assetsFilter = [ALAssetsFilter allVideos];picker.showEmptyGroups=NO;picker.delegate=self;picker.selectionFilter = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {if ([[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypeVideo]) {NSTimeInterval duration = [[(ALAsset*)evaluatedObject valueForProperty:ALAssetPropertyDuration] doubleValue];return duration >= 5;} else {return YES;}}];[self presentViewController:picker animated:YES completion:NULL];
}
#pragma mark - ZYQAssetPickerController Delegate
-(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{if(!_leftDataArr){_leftDataArr = [[NSMutableArray alloc] init];}for (int i=0; i<assets.count; i++) {ALAsset *asset=assets[i];ALAssetRepresentation * representation = asset.defaultRepresentation;//图片if(_uploadPicVideo == 1){UIImage *tempImg=[UIImage imageWithCGImage:representation.fullScreenImage];NSString *typeStr = @"图片";NSData *data;不能选择到图片的情况if(tempImg == nil){tempImg=[UIImage imageWithCGImage:asset.aspectRatioThumbnail];if(tempImg==nil){tempImg=[UIImage imageWithCGImage:asset.thumbnail];}data = UIImageJPEGRepresentation(tempImg, 1);NSString* picPath = [NSString stringWithFormat:@"%@/%@",KOriginalPhotoImagePath,representation.filename];NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];if(data){[objDict setObject:data forKey:@"header"];}[objDict setObject:picPath  forKey:@"path"];[objDict setObject:typeStr forKey:@"type"];[objDict setObject:representation.filename  forKey:@"name"];[_leftDataArr addObject:objDict];NSFileManager * fileManager = [NSFileManager defaultManager];if (![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {[fileManager createDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YES attributes:nil error:nil];}dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSString * imagePath = [KOriginalPhotoImagePath stringByAppendingPathComponent:representation.filename];[data writeToFile:imagePath atomically:YES];//UI的更新记得放在主线程,要不然等子线程排队过来都不知道什么年代了,会很慢的dispatch_async(dispatch_get_main_queue(), ^{[_tableView reloadData];});});}else{data = UIImageJPEGRepresentation(tempImg, 1);[self imageWithUrl:representation.url withFileName:representation.filename];NSString* picPath = [NSString stringWithFormat:@"%@/%@",KOriginalPhotoImagePath,representation.filename];NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];if(data){[objDict setObject:data forKey:@"header"];}[objDict setObject:picPath  forKey:@"path"];[objDict setObject:typeStr forKey:@"type"];[objDict setObject:representation.filename  forKey:@"name"];[_leftDataArr addObject:objDict];}//视频}else if (_uploadPicVideo == 2){UIImage *tempImg = [UIImage imageWithCGImage:asset.thumbnail];NSString *typeStr = @"视频";NSData *data = UIImageJPEGRepresentation(tempImg, 1);[self videoWithUrl:representation.url withFileName:representation.filename];NSString* picPath = [NSString stringWithFormat:@"%@/%@",KVideoUrlPath,representation.filename];NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];if(data){[objDict setObject:data forKey:@"header"];}[objDict setObject:picPath  forKey:@"path"];[objDict setObject:typeStr forKey:@"type"];[objDict setObject:representation.filename  forKey:@"name"];[_leftDataArr addObject:objDict];}}//视频tableview高度CGRect downRect = _downTableView.frame;downRect.size.height = 37+_leftDataArr.count*91;[_downTableView setFrame:downRect];[self adapterScrollViewAcion];
}// 将原始图片的URL转化为NSData数据,写入沙盒
- (void)imageWithUrl:(NSURL *)url withFileName:(NSString *)fileName
{// 进这个方法的时候也应该加判断,如果已经转化了的就不要调用这个方法了// 如何判断已经转化了,通过是否存在文件路径ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];// 创建存放原始图的文件夹--->PhotoImagesNSFileManager * fileManager = [NSFileManager defaultManager];if (![fileManager fileExistsAtPath:KOriginalPhotoImagePath]) {[fileManager createDirectoryAtPath:KOriginalPhotoImagePath withIntermediateDirectories:YES attributes:nil error:nil];}dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{if (url) {// 主要方法[assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {ALAssetRepresentation *rep = [asset defaultRepresentation];Byte *buffer = (Byte*)malloc((unsigned long)rep.size);NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:((unsigned long)rep.size) error:nil];NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];NSString * imagePath = [KOriginalPhotoImagePath stringByAppendingPathComponent:fileName];[data writeToFile:imagePath atomically:YES];// UI的更新记得放在主线程,要不然等子线程排队过来都不知道什么年代了,会很慢的dispatch_async(dispatch_get_main_queue(), ^{[_tableView reloadData];});} failureBlock:nil];}});
}// 将原始视频的URL转化为NSData数据,写入沙盒
- (void)videoWithUrl:(NSURL *)url withFileName:(NSString *)fileName
{// 解析一下,为什么视频不像图片一样一次性开辟本身大小的内存写入?// 想想,如果1个视频有1G多,难道直接开辟1G多的空间大小来写?// 创建存放原始图的文件夹--->VideoURLNSFileManager * fileManager = [NSFileManager defaultManager];if (![fileManager fileExistsAtPath:KVideoUrlPath]) {[fileManager createDirectoryAtPath:KVideoUrlPath withIntermediateDirectories:YES attributes:nil error:nil];}ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{if (url) {[assetLibrary assetForURL:url resultBlock:^(ALAsset *asset) {ALAssetRepresentation *rep = [asset defaultRepresentation];NSString * videoPath = [KVideoUrlPath stringByAppendingPathComponent:fileName];const char *cvideoPath = [videoPath UTF8String];FILE *file = fopen(cvideoPath, "a+");if (file) {const int bufferSize = 11024 * 1024;// 初始化一个1M的bufferByte *buffer = (Byte*)malloc(bufferSize);NSUInteger read = 0, offset = 0, written = 0;NSError* err = nil;if (rep.size != 0){do {read = [rep getBytes:buffer fromOffset:offset length:bufferSize error:&err];written = fwrite(buffer, sizeof(char), read, file);offset += read;} while (read != 0 && !err);//没到结尾,没出错,ok继续}// 释放缓冲区,关闭文件free(buffer);buffer = NULL;fclose(file);file = NULL;// UI的更新记得放在主线程,要不然等子线程排队过来都不知道什么年代了,会很慢的dispatch_async(dispatch_get_main_queue(), ^{[_tableView reloadData];});}} failureBlock:nil];}});
}@end

示意图:






这篇关于[IOS]从相册获取图片和视频进行上传的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1091506

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W