美文网首页unity
Unity功能记录(一) ------ 截图/录屏保存到相册(A

Unity功能记录(一) ------ 截图/录屏保存到相册(A

作者: 千喜Ya | 来源:发表于2019-07-04 21:27 被阅读5次

    截屏和录屏unity端代码都已经分享过 :
    Unity功能记录(十七) ------ 截屏功能
    Unity插件(二) ------ NatCorder(录屏保存到相册)

    但是之前一个个的其实并没有用在项目上,可能会有点小坑,因此此次用在项目上的完整代码再次记录一下


    一.截屏

    Unity端代码 :
     void RecordFrame()
        {
            DateTime now = new DateTime();
            now = DateTime.Now;
            string filename = string.Format("image{0}{1}{2}{3}.png", now.Day, now.Hour, now.Minute, now.Second);
            Texture2D texture = CaptureScreen(ARControll.Instance.CaptureCamera,new Rect(0,0,Screen.width,Screen.height));
            string destination = "";
            if (Application.platform == RuntimePlatform.Android)
            {
                destination = "/mnt/sdcard/DCIM/Screenshots";
                if (!Directory.Exists(destination))
                {
                    Directory.CreateDirectory(destination);
                }
                destination = destination + "/" + filename;
                Debug.Log(destination);
                File.WriteAllBytes(destination, texture.EncodeToPNG());
                // 安卓在这里需要去 调用原生的接口去 刷新一下,不然相册显示不出来
                using (AndroidJavaClass playerActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
                {
                    using (AndroidJavaObject jo = playerActivity.GetStatic<AndroidJavaObject>("currentActivity"))
                    {
                        Debug.Log("scanFile:m_androidJavaObject ");
                        jo.Call("scanFile", destination);
                    }
                }
                MainControll.Instance.OpenTip(TipType.OneBtn, TipContentType.defaultTip, null, null, "拍照成功!", PanelLayer.Top);
            }
            else if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                destination = Application.persistentDataPath;
                if (!Directory.Exists(destination))
                {
                    Directory.CreateDirectory(destination);
                }
                destination = destination + "/" + filename;
                File.WriteAllBytes(destination, texture.EncodeToPNG());
    #if UNITY_IOS
                IOSAlbumCamera.iosSaveImageToPhotosAlbum(destination);
    #endif
            }
            else
            {
                File.WriteAllBytes(Application.persistentDataPath + filename, texture.EncodeToPNG());
            }
            // cleanup
            Destroy(texture);
        }
    
    Android刷新相册代码 :
       //刷新相册
        public void scanFile(String filePath) {
            //Log.i("Unity", "------------filePath"+filePath);
            Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            scanIntent.setData(Uri.fromFile(new File(filePath)));
            this.sendBroadcast(scanIntent);  //this是指UnityPlayerActivity
        }
    
    iOS保存图片到相册代码(这里一起放了保存视频到相册的代码) :

    IOSAlbumCameraController.h :

    #import<QuartzCore/CADisplayLink.h>
    @interface IOSAlbumCameraController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIPopoverPresentationControllerDelegate>
    @end
    

    IOSAlbumCameraController.mm :

    #import "IOSAlbumCameraController.h"
    
    @implementation IOSAlbumCameraController
    - (void)leftAction
    {
        [self interfaceOrientation:UIInterfaceOrientationPortrait];
    }
    
    - (void)rightAction
    {
        [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
    }
    
    - (void)interfaceOrientation:(UIInterfaceOrientation)orientation
    {
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
            SEL selector             = NSSelectorFromString(@"setOrientation:");
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
            [invocation setSelector:selector];
            [invocation setTarget:[UIDevice currentDevice]];
            int val                  = orientation;
            // 从2开始是因为0 1 两个参数已经被selector和target占用
            [invocation setArgument:&val atIndex:2];
            [invocation invoke];
        }
    }
    -(void)OpenCamera:(UIImagePickerControllerSourceType)type{
        [self interfaceOrientation:UIInterfaceOrientationPortrait];
        //创建UIImagePickerController实例
        UIImagePickerController * picker = [[UIImagePickerController alloc] init];
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
        
        //设置代理
        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;
            //picker.preferredContentSize = [UIScreen mainScreen].bounds.size;
            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:^{}];
        }
    }
    -(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"];
        }
        //图片旋转
        if (image.imageOrientation != UIImageOrientationUp) {
            //图片旋转
            image = [self fixOrientation:image];
        }
        NSString *imagePath = [self GetSavePath:@"Temp.jpg"];
        [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{
        [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
        UnitySendMessage("MainScriptHolder", "PicCallFunc", "Temp.jpg");
        NSData *data;
        if (UIImagePNGRepresentation(image)==nil) {
            data = UIImageJPEGRepresentation(image, 1);
        }else{
            data = UIImagePNGRepresentation(image);
        }
        [data writeToFile:path atomically:YES];
    }
    // 打开相册后点击“取消”的响应
    - (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker
    {
        NSLog(@" --- imagePickerControllerDidCancel !!");
        [self interfaceOrientation:UIInterfaceOrientationLandscapeRight];
        UnitySendMessage( "MainScriptHolder", "PicCallFunc", (@"").UTF8String);
        [self dismissViewControllerAnimated:YES completion:nil];
    }
    #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) saveImageToPhotosAlbum:(NSString*) readAdr
    {
        NSLog(@"readAdr: ");
        NSLog(readAdr);
        UIImage* image = [UIImage imageWithContentsOfFile:readAdr];
        UIImageWriteToSavedPhotosAlbum(image,
                                       self,
                                       @selector(image:didFinishSavingWithError:contextInfo:),
                                       NULL);
    }
    
    +(void) image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
    {
        NSString* result;
        if(error)
        {
            result = @"图片保存到相册失败!";
        }
        else
        {
            result = @"图片保存到相册成功!";
        }
        UnitySendMessage( "MainScriptHolder", "SaveImageToPhotosAlbumCallBack", result.UTF8String);
    }
    //videoPath为视频下载到本地之后的本地路径
    + (void)saveVideo:(NSString *)videoPath{
        
        NSLog(@"路径:%@",videoPath);
        if (videoPath) {
            NSURL *url = [NSURL URLWithString:videoPath];
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(url.path) == NO) {
                NSLog(@"可以保存 ");
            }
            else
            {  NSLog(@"不可以保存 ");
            }
            //保存相册核心代码
            UISaveVideoAtPathToSavedPhotosAlbum(url.path, self, @selector(savedVedioImage:didFinishSavingWithError:contextInfo:), nil);
        }
    }
    //保存视频完成之后的回调
    + (void) savedVedioImage:(UIImage*)image didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo {
        NSString* result;
        if (error) {
            result =@"视频保存失败";
        }
        else {
            result =@"保存视频成功";
        }
        UnitySendMessage( "MainScriptHolder", "SaveVedioToPhotosAlbumCallBack", result.UTF8String);
    }
    @end
    
    #if defined (__cplusplus)
    extern "C" {
    #endif
        // 打开相册
        void _iosOpenPhotoAlbums()
        {
            IOSAlbumCameraController *app = [[IOSAlbumCameraController alloc]init];
            UIViewController *vc = UnityGetGLViewController();
            [vc.view addSubview:app.view];
            [app OpenCamera:UIImagePickerControllerSourceTypePhotoLibrary];
        }
        void _iosSaveImageToPhotosAlbum(char* readAddr)
        {
            NSString* temp = [NSString stringWithUTF8String:readAddr];
            [IOSAlbumCameraController saveImageToPhotosAlbum:temp];
        }
        
        void _iosSaveVideoToPhotosAlbum(char* readAddr)
        {
            NSString* temp = [NSString stringWithUTF8String:readAddr];
            [IOSAlbumCameraController saveVideo:temp];
        }
        
    #if defined (__cplusplus)
    }
    #endif
    

    unity与iOS交互代码IOSAlbumCamera.cs :

    using UnityEngine;
    using System.Collections;
    using System.Runtime.InteropServices;
    
    public class IOSAlbumCamera : MonoBehaviour
    {
    #if UNITY_IOS 
        [DllImport ("__Internal")]
        private static extern void _iosOpenPhotoAlbums();
        [DllImport ("__Internal")]
        private static extern void _iosSaveImageToPhotosAlbum(string readAddr);
        [DllImport("__Internal")]
        private static extern void _iosSaveVideoToPhotosAlbum(string readAddr);
    
        /// <summary>
        /// 保存图片到相册
        /// </summary>
        /// <param name="readAddr"></param>
        public static void iosSaveImageToPhotosAlbum(string readAddr)
        {
            _iosSaveImageToPhotosAlbum (readAddr);
        }
    
        public static void iosSaveVideoToPhotosAlbum(string readAddr)
        {
            _iosSaveVideoToPhotosAlbum(readAddr);
        }
        public static void iosOpenPhotoAlbums()
        {
            _iosOpenPhotoAlbums();
        }
    #endif
    }
    

    注意修改回调哦

    二.录屏

    unity代码请参考Unity插件(二) ------ NatCorder(录屏保存到相册)
    保存到相册请参考一中iOS所有代码

    相关文章

      网友评论

        本文标题:Unity功能记录(一) ------ 截图/录屏保存到相册(A

        本文链接:https://www.haomeiwen.com/subject/fmnchctx.html