Unity XCode iOS 实现拍照和相册选择上传头像

2023-11-16

在这里插入图片描述

显示弹窗

通过UIAlertController来创建一个弹窗

#if defined(__cplusplus)
extern "C" {
#endif
    //导出接口供unity使用
    void IOS_Open(){
      IOSCameraController*   app = [[IOSCameraController alloc]init];
        [app Open];
    }
#if defined(__cplusplus)
}
#endif
-(void)Open{
    //创建窗口
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"上传图片" message:@"选择上传图片的方式" preferredStyle:UIAlertControllerStyleAlert];
    //创建按钮
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
    }];
    
    UIAlertAction *camera = [UIAlertAction actionWithTitle:@"拍照上传" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
        [self OpenCamera];
    }];
   
    UIAlertAction *album = [UIAlertAction actionWithTitle:@"相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){
        [self OpenAlbum];
    }];
    //添加按钮
    [alertController addAction:cancel];
    [alertController addAction:camera];
    [alertController addAction:album];
    
    while(alertController.presentedViewController)
    {
    }
//显示窗口
    [UnityGetGLViewController() presentViewController:alertController animated:YES completion:^(){}];
}

打开相机和相册

// UIImagePickerControllerSourceTypePhotoLibrary,      // 来自图库
    // UIImagePickerControllerSourceTypeCamera,            // 来自相机
    // UIImagePickerControllerSourceTypeSavedPhotosAlbum   // 来自相册
-(void)OpenTarget:(UIImagePickerControllerSourceType)type{
    //创建UIImagePickerController实例
    UIImagePickerController *picker;
    picker= [[UIImagePickerController alloc]init];
    //设置代理
    picker.delegate = self;
    //是否允许编辑 (默认为NO)
    picker.allowsEditing = YES;
    //设置照片的来源
    picker.sourceType = type;
    if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary &&[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        // 设置弹出的控制器的显示样式
        picker.modalPresentationStyle = UIModalPresentationPopover;
        //获取这个弹出控制器
        UIPopoverPresentationController *popover = picker.popoverPresentationController;
        //设置代理
        popover.delegate = self;
        //下面两个属性设置弹出位置
        popover.sourceRect = CGRectMake(0, 0, 0, 0);
        popover.sourceView = self.view;
        //设置箭头的位置
        popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
        //展示选取照片控制器
        [self presentViewController:picker animated:YES completion:nil];
    } else {
        //展示选取照片控制器
        [self presentViewController:picker animated:YES completion:^{}];
    }
}
//选择完成,点击界面中的某个图片或者选择(Choose)按钮时触发
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    //关闭界面
    [picker dismissViewControllerAnimated:YES completion:^{}];
    //得到照片
    UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
    if (image == nil) {
        image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    }
    //有些时候我们拍照后经常发现导出的照片方向会有问题,要么横着,要么颠倒着,需要旋转才适合观看。但是在ios设备上是正常的
    //所以在这里处理了图片  让他旋转成我们需要的
    if (image.imageOrientation != UIImageOrientationUp) {
    //图片旋转
        image = [self fixOrientation:image];
    }
    //获取保存图片的地址
    NSString *imagePath = [self GetSavePath:@"xp.jpg"];
    //保存图片到沙盒路径 对应unity中的Application.persistentDataPath 之后我们取图片就需要在这个路径下取  这是一个可读可写的路径
    [self SaveFileToDoc:image path:imagePath];
}
//选择完成,点击界面中的某个图片或者选择(Choose)按钮时触发
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    //关闭界面
    [picker dismissViewControllerAnimated:YES completion:^{}];
    //得到照片
    UIImage *image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
    if (image == nil) {
        image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    }
    //有些时候我们拍照后经常发现导出的照片方向会有问题,要么横着,要么颠倒着,需要旋转才适合观看。但是在ios设备上是正常的
    //所以在这里处理了图片  让他旋转成我们需要的
    if (image.imageOrientation != UIImageOrientationUp) {
    //图片旋转
        image = [self fixOrientation:image];
    }
    //获取保存图片的地址
    NSString *imagePath = [self GetSavePath:@"Temp.jpg"];
    //保存图片到沙盒路径 对应unity中的Application.persistentDataPath 之后我们取图片就需要在这个路径下取  这是一个可读可写的路径
    [self SaveFileToDoc:image path:imagePath];
}
//获取保存文件的路径 如果有返回路径 没有创建一个返回
-(NSString*)GetSavePath:(NSString *)filename{
    NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [pathArray objectAtIndex:0];
    return [docPath stringByAppendingPathComponent:filename];
}
//将图片保存到沙盒路径
-(void)SaveFileToDoc:(UIImage *)image path:(NSString *)path{
    NSData *data;
    if (UIImagePNGRepresentation(image)==nil) {
        data = UIImageJPEGRepresentation(image, 1);
    }else{
        data = UIImagePNGRepresentation(image);
    }
    [data writeToFile:path atomically:YES];

    char* pathStr = [path cStringUsingEncoding:NSASCIIStringEncoding];
    UnitySendMessage("Setting", "CallbackImagePath", pathStr);
}
#pragma mark 图片处理方法
//图片旋转处理
- (UIImage *)fixOrientation:(UIImage *)aImage {
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (aImage.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                             CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                             CGImageGetColorSpace(aImage.CGImage),
                                             CGImageGetBitmapInfo(aImage.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (aImage.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
            break;
    }
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    return img;
}

打开相册

-(void) OpenCamera{
    IOSCameraController *app = [[IOSCameraController alloc]init];
//IOSCameraController是提供给Unity调用的object-c脚本
    UIViewController *vc = UnityGetGLViewController();
    [vc.view addSubview:app.view];
    [app OpenTarget:UIImagePickerControllerSourceTypeCamera];
}

打开相机

-(void) OpenCamera{
    IOSCameraController *app = [[IOSCameraController alloc]init];
//IOSCameraController是提供给Unity调用的object-c脚本

    UIViewController *vc = UnityGetGLViewController();
    [vc.view addSubview:app.view];
    [app OpenTarget:UIImagePickerControllerSourceTypeCamera];
}

注意事项

同一个UIAlertController不同使用两个UIAlertActionStyleCancel类型的UIAlertAction

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity XCode iOS 实现拍照和相册选择上传头像 的相关文章

  • iOS 中的等宽字体是什么?

    我想要在我的 iOS 应用程序中为 UILabel 使用等宽字体 不幸的是 我找不到一个 甚至 美国打字机 实际上也不是等宽的 XCode 中可用的等宽字体是什么 iOS 等宽字体 Courier Courier Bold Courier
  • XCode:代码覆盖率数据生成失败

    当我尝试运行单元测试时 我在 Objective C 项目中遇到了这个可怕的问题 我已经尝试了以下所有方法 根据各种 SOF 帖子 清除派生数据 删除 Library 中的所有模拟器设置 重新启动 XCode 重新启动MBP 多次重置模拟器
  • 从 Core Data、iOS 获取最后插入的项目

    有没有办法获取核心数据数据库中最后插入的项目 这将返回最后插入的对象 setFetchLimit 1 和 setFetchOffset 所有条目数 1
  • 更改 UITextField 辅助功能描述

    有没有办法将 UITextField 的辅助功能标签设置为 文本字段 之外的其他内容 因此 我不想将其称为 文本字段 而是将其命名为 代码验证字段 我的建议是不要试图在内置语音输出上智取系统 对于盲人用户来说 文本字段正在编辑 相当于 该项
  • 如何使用自签名证书为 TLS 创建 iOS NWConnection?

    我正在尝试将 Apple 的新 NWConnection 类用于我的 MQTT 客户端 为了进行测试 我需要能够创建到本地测试代理的 TLS 连接 该代理具有自签名证书 到目前为止 我只是使用以下命令设置连接 self connection
  • 在 Swift 中检查一个数组是否包含另一个数组的所有元素

    我想为数组编写一个扩展来检查一个数组是否包含另一个数组的所有元素 在我的用例中它是字符串对象 但我一直得到 Cannot convert value of type T Generator Element to expected argum
  • UIImage:如何获取网站选项卡图标

    我正在开发一个 RSS 阅读器 我需要获取每个提要的图标 例如 如果我的提要是 google com 我想获取 G 图标并将其放入 UIImage 或其他内容中 关于如何实现这一目标有什么想法吗 最简单的方法是使用 Google NSStr
  • 如何在ios中以编程方式添加水平间距和垂直间距?

    我在 ios 8 中创建了一个应用程序 因为我有 4 个可垂直使用的标签 它应该在某些条件下更改位置 所以我已禁用自动布局并以编程方式设置约束 现在的问题是 我可以设置水平和垂直位置 宽度和高度的约束 但我找不到任何方法来添加标签之间的水平
  • iOS 对 Google 云消息传递的支持

    我在谷歌的开发者控制台中看到 GCM 允许为 iOS 生成 API 密钥 我在网上搜索了有关如何在 iOS 应用程序中通过 GCM 实现推送通知的任何类型的文档 但没有找到答案 真的有可能在 iOS 应用程序中使用 GCM 实现推送通知 j
  • 下标:使用字符串枚举访问我的字典值

    我想做类似的事情 使用字符串枚举访问我的字典值 我试图重载字典的下标但没有成功 访问字典 let district address JsonKeys district 其中 JsonKeys 是 enum JsonKeys String c
  • 具有非零“内容”的 QTMovieLayer 的 iOS 替代品?

    背景 QTKit QuickTime Kit 是一个来自 10 3 天的 Mac 框架 在 10 5 中添加了一些层 例如QTMovieLayer QTMovieLayer 的好处之一是您可以使用常规访问电影内容content图层上的属性并
  • 访问iOS 7隐藏的UITableViewCellScrollView?

    苹果改变了UITableViewCelliOS 7 中的层次结构 使用iOS 6 1 SDK
  • UIViewController 作为单例

    我在标签栏应用程序中有一个 UIViewController 我已经从 MainWindow nib 文件添加了控制器 即不是以编程方式 我的问题是如何使我的视图控制器成为单例 解决 Facebook 委托问题 您可能想让您的 Facebo
  • Apple 帮助创作

    我正在跟进本指南 http developer apple com library mac documentation Carbon Conceptual ProvidingUserAssitAppleHelp authoring help
  • 删除部分(红色删除按钮),UITableViewController - iOS

    我正在尝试做一个分组的 uitableview 并且我已经激活了编辑选项 我希望用户也能够删除整个部分 而不仅仅是特定行 因此 当您单击 编辑 时 每个表格单元格左侧显示的红色减号按钮也应该显示在各个部分 部分标题左侧 有人知道如何做到这一
  • 在 swift 中设置状态栏的自定义颜色?

    在视图控制器上 我想将状态栏的颜色设置为黑色 但我无法更改它 我为此目的使用下面的代码 func setUpUI self navigationController setNavigationBarHidden true animated
  • Xcode UI 测试 - 通过 id 在 Webview 中查找元素

    我们的应用程序是混合的 包含 webview 我正在尝试使用 Xcode UI 测试自动化我们的应用程序 我能够使用以下方法找到网络按钮 let app XCUIApplication app launch let button app s
  • ios - 使用 SIGPIPE 和 SIG_IGN 的信号函数

    我加入了一个旧项目 我发现了这条线 BOOL application UIApplication application didFinishLaunchingWithOptions NSDictionary launchOptions si
  • Flutter - 删除 ListView 中项目之间的空间

    我正在使用 ListView builder 函数来创建项目列表 然而 iOS 中每个项目之间的空间很大 截图 你知道如何删除项目吗 看来是默认的 因为我没有添加它 code 列表显示 return Scaffold body ListVi
  • 我正在寻找 GCDAsyncUdpSocket 上的一些示例,但发现没有一个有效

    接收数据从未被调用过 我编写了这个由我的主线调用的 swift 类UI视图控制器向接收消息的服务器发送消息 但当服务器发回响应时 客户端永远不会收到它 因为 didReceiveData 从未被触发 我一直在谷歌上搜索并查看文档 它说客户端

随机推荐

  • LM算法初识

    由于工作内容接触到点云标定 需要用到最小二乘法 所以特意花了点时间研究LM算法 但是由于大学的高等数学忘得差不多了 所以本文从最基本的一些数学概念开始 信赖域法 在最优化算法中 都是要求一个函数的极小值 每一步迭代中 都要求目标函数值是下降
  • canvas系列教程之填充颜色

    艺术离不开色彩 今天咱们来介绍一下填充颜色 体会一下色彩的魅力 填充颜色主要分为两种 基本颜色 渐变颜色 又分为线性渐变与径向渐变 我们一个个来看 填充基本颜色 Canvas fillStyle属性用来设置画布上形状的基本颜色和填充 fil
  • Python + Django4 搭建个人博客(二十):阿里云部署博客项目

    本篇我们将完成我们搭建个人博客的核心功能的最后一篇 部署上线 接下来部分我们将不定期更新一些其他的博客功能 比如 文章栏目 消息通知 用户扩展等小功能模块 目录 准备服务器 安装Xshell 和Xftp 服务器安装软件 安装Mysql 修改
  • vue-loade和vue的版本问题,webpack5

    npm add D vue template compiler 2 6 14 vue loader 15 9 8 const VueLoaderPlugin require vue loader vue加载器 使用node语法获得动态路径
  • Nginx配置文件详细说明

    原创 http www cnblogs com xiaogangqq123 archive 2011 03 02 1969006 html 在此记录下Nginx服务器nginx conf的配置文件说明 部分注释收集与网络 运行用户 user
  • 微信小程序:自定义导航栏

    看到有的微信小程序的页面左上角有了个 小房子 可以返回首页 这是怎么做到的 其实这是微信开放的自定义的自定义导航栏来完成 但是最开始 对于一个页面很多的小程序 其实有点一言难尽 因为你自定义 你可能要所有页面都要添加一遍 现在小程序可以自定
  • 34. Search for a Range

    这道题一开始没看别人的算法 第一个想法是用递归做 自己憋了两个小时终于憋出来了 然而超时 递归的想法是先用二分法找到一个target 然后从target左右再用二分法找边界 然而 真的是 太慢了 class Solution public
  • VSCode问题记录

    20230304 0 引言 这几年的编程方式还真是各种变化 从一开始直接VIM 到后面使用jupyter进行机器学习相关 然后再过渡到vim的形式并加以tmux批量化 最后去年使用了vscode作为IDE 随着工具的变化 那么很多习惯也都随
  • UnityVR--EventManager--事件中心2

    目录 前言 事件中心的结构 EventManager事件管理器 EventType事件类型 EventListener监听及回调 EventDataBase回调时需要传递的参数 总结 前言 上一篇 事件中心1 中 简单解释了委托 事件 监听
  • 【Java SE】类和对象(全网最细详解)

    点进来你就是我的人了博主主页 戳一戳 欢迎大佬指点 欢迎志同道合的朋友一起加油喔 目录 前言 一 面向对象的初步认知 1 什么是面向对象 2 面向对象和面向过程的区别 二 类和对象的基本概念 三 类和对象的定义和使用 1 类的创建 2 对象
  • 数据库的url配置8.0

    spring datasource username root spring datasource password lhh12345 spring datasource url jdbc mysql localhost 3306 myba
  • numpy.diag()结构及用法

    numpy diag v k 0 官方文档 以一维数组的形式返回方阵的对角线 或非对角线 元素 或将一维数组转换成方阵 非对角线元素为0 两种功能角色转变取决于输入的v 1 更深层的见numpy diagnal 参数详解 v array l
  • windows获取系统DPI

    dc GetDeviceCaps LOGPIXELSX 每英寸水平逻辑像素数 dc GetDeviceCaps LOGPIXELSY 每英寸垂直逻辑像素数 dc GetDeviceCaps HORZRES 水平像素总数 dc GetDevi
  • [Java]获取java方法注释实例

    Method methods company class getMethod getId null PK pk methods getAnnotation PK class System out println pk
  • vue指令中v-show和v-if以及keep-alive的区别

    v if 属于条件显示 满足条件就显示元素 不满足就删除元素 通过操作DOM元素完成 v if的首次渲染显示的开销较小 因为它只渲染满足条件的那一个元素 切换组件时 其开销较大 因为它每切换以此就要重新触发生命周期渲染显示新元素 v if值
  • JS实现轮播图(自动+手动)

    网页轮播图效果 核心原理 tips 代码在文章末尾 这个ul就是我们这四张图片的父盒子 我们通过对这个父盒子添加动画函数来实现移动 然后给父盒子来一个溢出隐藏就达到了轮播的效果 动画函数如下 function animate obj tar
  • 【python爬虫】8.温故而知新

    文章目录 前言 回顾前路 代码实现 体验代码 功能拆解 获取数据 解析提取数据 存储数据 程序实现与总结 前言 Hello又见面了 上一关我们学习了爬虫数据的存储 并成功将QQ音乐周杰伦歌曲信息的数据存储进了csv文件和excel文件 学到
  • 8.typescript-函数的类型

    今儿个甚是乏累呢 但是 lt 下面可能是正题儿 gt 1 函数声明 1 function student x string y number string 2 return 我是 x 今年 y 岁 3 4 5 console log stu
  • 商品期货怎么玩? 1手交易需要多少钱?

    期货市场中有许多大宗商品 把他们统称为商品期货 近几年我国商品期货品种不时在增加 固然期货风险比较高 但收益也十分可观 而且商品期货开户几乎没有门槛 国内商品期货免费开户 无资金限制 凭身份证和银行卡即可办理 开设期货帐户 能在网上开期货帐
  • Unity XCode iOS 实现拍照和相册选择上传头像

    显示弹窗 通过UIAlertController来创建一个弹窗 if defined cplusplus extern C endif 导出接口供unity使用 void IOS Open IOSCameraController app I