IOS相对简单,没有那么多版本适配问题,只有一些权限需要设置
已经处理了图像大小
获取摄像头权限 Privacy - Photo Library Usage Description
Unity 通讯 OC
[DllImport("__Internal")]
private static extern void IOS_OpenCamera();
[DllImport("__Internal")]
private static extern void IOS_OpenAlbum();
public static void GetPhotoAndFolderHead()
{
if (Application.platform != RuntimePlatform.OSXEditor)
IOS_OpenAlbum();
}
public static void OpenCameraHeadIcon()
{
if (Application.platform != RuntimePlatform.OSXEditor)
IOS_OpenCamera();
}
Objective-C 需要两个文件
需要两个文件夹
IOSCameraController.h
//import 引用头文件 相当远Using
#import<QuartzCore/CADisplayLink.h>
//声明一个IOSCameraController类 继承自UIViewController <>里面是是协议/代理的调用声明 可以理解为c#的接口
@interface IOSCameraController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@end
IOSCameraController.m
#import "IOSCameraController.h"
@implementation IOSCameraController
-(void)OpenTarget:(UIImagePickerControllerSourceType)type{
//创建UIImagePickerController实例
UIImagePickerController *picker;
picker= [[UIImagePickerController alloc]init];
//设置代理
picker.delegate = self;
//是否允许编辑 (默认为NO)
picker.allowsEditing = YES;
//设置照片的来源
// UIImagePickerControllerSourceTypePhotoLibrary, // 来自图库
// UIImagePickerControllerSourceTypeCamera, // 来自相机
// UIImagePickerControllerSourceTypeSavedPhotosAlbum // 来自相册
picker.sourceType = type;
//这里需要判断设备是iphone还是ipad 如果使用的是iphone并没有问题 但是如果 是在ipad上调用相册获取图片 会出现没有确定(选择)的按钮 所以这里判断
//了一下设备,针对ipad 使用另一种方法 但是这种方法是弹出一个界面 并不是覆盖整个界面 需要改进 试过另一种方式 重写一个相册界面
//(QQ的ipad选择头像的界面 就使用了这种方式 但是这里我们先不讲 (因为我也不太懂 但是我按照简书的一位老哥的文章写出来了 这里放一下这个简书的链接
//https://www.jianshu.com/p/0ddf4f7476aa)
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];
}
// image =[self compressOriginalImagea:image ]
//获取保存图片的地址
[self createDir];
CGSize size = CGSizeMake(100.0f, 100.0f);
image=[self imageCompressForSize:image targetSize:size];
NSString *imagePath = [self GetSavePath:@"/headIcon/Temp.jpg"];
//保存图片到沙盒路径 对应unity中的Application.persistentDataPath 之后我们取图片就需要在这个路径下取 这是一个可读可写的路径
[self SaveFileToDoc:image path:imagePath];
}
/**
* 压缩图片到指定尺寸大小
*
* @param image 原始图片
* @param size 目标大小
*
* @return 生成图片
*/
-(UIImage *) imageCompressForSize:(UIImage *)sourceImage targetSize:(CGSize)size{
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = size.width;
CGFloat targetHeight = size.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
if(CGSizeEqualToSize(imageSize, size) == NO){
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if(widthFactor > heightFactor){
scaleFactor = widthFactor;
}
else{
scaleFactor = heightFactor;
}
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
if(widthFactor > heightFactor){
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
}else if(widthFactor < heightFactor){
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
UIGraphicsBeginImageContext(size);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
if(newImage == nil){
NSLog(@"scale image fail");
}
UIGraphicsEndImageContext();
return newImage;
}
//获取保存文件的路径 如果有返回路径 没有创建一个返回
-(NSString*)GetSavePath:(NSString *)filename{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [pathArray objectAtIndex:0];
return [docPath stringByAppendingPathComponent:filename];
}
#pragma mark 使用NSSearchPathForDirectoriesInDomains创建文件目录
- (void)createDir {
NSString * docsdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *dataFilePath = [docsdir stringByAppendingPathComponent:@"headIcon"]; // 在Document目录下创建 "archiver" 文件夹
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir = NO;
// fileExistsAtPath 判断一个文件或目录是否有效,isDirectory判断是否一个目录
BOOL existed = [fileManager fileExistsAtPath:dataFilePath isDirectory:&isDir];
if (!(isDir && existed)) {
// 在Document目录下创建一个archiver目录
[fileManager createDirectoryAtPath:dataFilePath withIntermediateDirectories:YES attributes:nil error:nil];
}
// 在archiver下写入文件
NSString *path = [dataFilePath stringByAppendingPathComponent:@"my.txt"];
NSString *text = @"It's a beautiful day.";
BOOL writeSuccess = [text writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (writeSuccess) {
NSLog(@"写入成功");
}
}
//将图片保存到沙盒路径
-(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];
//保存之后通知unity 执行对应的回调
//UnitySendMessage 是用来给unity发消息的 有三个参数 1.挂载对应回调脚本的物体名 2.回调函数的名称 3.对应回调上的参数
UnitySendMessage("Root", "photoOk", "Temp.jpg");
}
#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;
}
@end
//由于C++编译器需要支持函数的重载,会改变函数的名称,因此dll的导出函数通常是标准C定义的。
//这就使得C和C++的互相调用变得很常见。但是有时可能又会直接用C来调用,不想重新写代码,
//让标准C编写的dll函数定义在C和C++编译器下都能编译通过,通常会使用以下的格式:(这个格式在很多成熟的代码中很常见)
#if defined(__cplusplus)
extern "C" {
#endif
//导出接口供unity使用
void IOS_OpenCamera(){
IOSCameraController *app = [[IOSCameraController alloc]init];
UIViewController *vc = UnityGetGLViewController();
[vc.view addSubview:app.view];
[app OpenTarget:UIImagePickerControllerSourceTypeCamera];
}
void IOS_OpenAlbum(){
IOSCameraController *app = [[IOSCameraController alloc]init];
UIViewController *vc = UnityGetGLViewController();
[vc.view addSubview:app.view];
[app OpenTarget:UIImagePickerControllerSourceTypePhotoLibrary];
}
#if defined(__cplusplus)
}
#endif