结合NGUI做的手机拍照(可自定义相框)

原地址:http://www.unity蛮牛.com/thread-18220-1-1.html

在次此之前我们先要了解一下下面的我要讲的几个内容:

一、为什么要用NGUI,因为NGUI的可以做屏幕自适应,在各大不同手机分辨率的屏幕上想要实现基本的显示而且不乱象的效果最后还又能快速开发出来,那么无疑还是NGUI比较的好。
二、既然是涉及到手机拍照,那么无疑使可以调用前置或者后置的摄像头都可以进行拍照咯。

三、实际上我做的所谓的拍照时利用了手机的截图功能,只是我会在最后保存路径上会将它保存到手机的相册上(这是个难点),论坛里看到过一篇转自雨松MOMO的有关安卓上打开摄像头拍照和打开本地相册的帖子的朋友一定会问为什么不使用这个方法来调用摄像机拍照呢。这个帖子我也大致的浏览了一下(MOMO的工程文件我还在网上找了下载了发到手机上不知道为啥不能运行成功),并不能满足我要做一个自己定义我的摄像机里面要有自定义的素材,比如拍一个大头贴,或者和选择一个明星照片作为背景之类的,总之肯定是不能调用手机自带的摄像机软件来拍照,因为那个软件是手机自带的根本无法用程序来控制所以也就做不到这点。那么我们只能是采用另外一种办法,摄像头无疑还是可以打开的,因为这个是可以通过调用硬件的驱动程序来实现。好在unity有这个的代码类的接口程序给我调用。然后再采用截图的方法实现拍照,这样在有NGUI的强大功能下,我们想实现什么自定义背景或者相框甚至是一个模型都是可控的。

前面唠叨了拿了多,开始我正式的讲解把。首先,还是一个NGUI的自适应问题,相信很多大婶朋友都是了如指掌了,但是我还是要在这里贴出一些我的做法和想法,大婶朋友如果发我的做法有不对的地方还望你不吝指出,在下感激不尽。

一、要做到自适应无非就是两个NGUI的脚本使用,一个是UIAnchor,另一个是UIStretch。作为界面显示使用2DUIRoot并做如图的设置

针对图片直接将UIStretch脱到图片上,然后再如图

。针对按钮就要两个同时使用,按钮的大小和位置都要保证自适应。如果你不是使用NGUI的图片按钮控件,而是自己做的一个按钮,比如都在就在一个物体上那么还要做如下设置 。这样就能保证按钮的碰撞体随着缩放而自动调整,不至于出现按钮图片自适应但是碰撞体没有自适应。

二、下面是怎么调用摄像头的问题。首先我们要如下的代码

[C#] 纯文本查看 复制代码

?


01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

public WebCamTexture cameraTexture; 

    public string cameraName=""

    private bool isPlay = false;

    public UITexture uiCameraTexture;[/size][size=3]    float zoomRate = 2;

    // Use this for initialization  

    void Start() 

    {

        StartCoroutine(openCamera(0));  //在程序运行的时候就打开摄像头

    

  

    // Update is called once per frame  

    void Update() 

    {

        if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home))//手机上按到home或者返回键退出程序

        {

            Application.Quit();

        }

    

  

    IEnumerator openCamera(int whichOne)  //打开摄像头,参数0表示后置摄像头,1表示前置摄像头

    

        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);  //获取手机的权限

        if (Application.HasUserAuthorization(UserAuthorization.WebCam)) 

        

            //可以通过下面的这个数组的索引来选择调用手机上的前置或者后置摄像头,另外这个可以自动对焦(这是个非常有用的功能)

            WebCamDevice[] devices = WebCamTexture.devices;

            if (devices.Length <= whichOne)

            {

                cameraName = devices[0].name;

            }

            else

            {

                cameraName = devices[whichOne].name;

            }

     

            cameraTexture = new WebCamTexture(cameraName,Screen.height,Screen.width,15); 

            cameraTexture.Play();

            isPlay = true

        

    

  

    void OnGUI() 

    

        if (isPlay) 

        {

            uiCameraTexture.mainTexture = cameraTexture;

            NGUIDebug.Log(cameraName);[/size][size=3]            uiCameraTexture.width = cameraTexture.width ;

            uiCameraTexture.height = cameraTexture.height;

            uiCameraTexture.transform.localScale = new Vector3(zoomRate, zoomRate, zoomRate);

        

    }[/size]

[size=3]  //双击拍照键就可以实现切换后置摄像头

    void ImgBtnTakePictureOnDoubleclik()

    {

        //NGUIDebug.Log("ssss");

        cameraTexture.Stop();

        StopAllCoroutines();

        StartCoroutine(openCamera(1));

    }

代码都有比较详细的说明,在这里我主要讲一下这段代码
uiCameraTexture.width = cameraTexture.width ; 
uiCameraTexture.height = cameraTexture.height;
uiCameraTexture.transform.localScale = new Vector3(zoomRate, zoomRate, zoomRate);
经过我的多次真机测试发现摄像头获取的图像的分辨率是和摄像头设备硬件直接相关的,我用红米手机的前置摄像头测试的时候得到的图像是600*800然而使用电脑上的微软的摄像头得到的是480*600,所以如果只是单纯的这样
uiCameraTexture.width = cameraTexture.width ; 
uiCameraTexture.height = cameraTexture.height;赋值那么得到的图像势必不是适应屏幕的,就一定会是小了。所以就有了后面那句等比例放大的代码。其实我本来前面还有一句代码,是根据手机的分辨率来判断我应该放大多大

[C#] 纯文本查看 复制代码

?


1

2

3

float heightRate = Screen.height / cameraTexture.height;

           float widthRate = Screen.width / cameraTexture.width;

           zoomRate = heightRate > widthRate ? heightRate : widthRate;

发现得到的ZoomRate都比较大(红米测试机上得到的是61),所以得到的图像基本上都是放大了几十倍的,最后是测试得到放到2倍是最理想的。其实这个给了我最后一个想法就是可以实现手指放大图像或者缩小来摄像类似于真正的手机上的照相软件那样。最后还要添加一个UITexture控件到scene上就OK啦。那么到这里基本上框架已经搭建好了而且一些设备的细节问题也得到了妥善的解决。最后当然是重头戏——怎么拍照。

三、怎么样实现不同手机上(安卓和苹果)的截图保存到手机上相册功能
想要实现不同的手机上都可以保存到相册中,这个无疑要借助到第三方的插件。插件的地址在我文章的后面可以下载。这里我主要讲一下腰注意的事项,如图

其实就是发布的时候获取手机的SD卡读取权限在图中的Writer Access里面选择External(SDCard)这一项。
然后修改之前的代码如下

[C#] 纯文本查看 复制代码

?


001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

public AudioSource shootSnd;

    public UITexture uiCameraTexture;

    public UISprite ImgBtnTakePictureUISprite;

    public BoxCollider ImgBtnTakePictureBoxCollider;

    WebCamTexture cameraTexture;

    float zoomRate;

    string cameraName = "";

    bool isPlay = false;

    bool saved = false;

    

    // Use this for initialization  

    void Start() 

    {

        StartCoroutine(openCamera(0));

        zoomRate = 1;

        ScreenshotManager.ScreenshotFinishedSaving += ScreenshotSaved;

    }

    void ScreenshotSaved()

    {

        saved = true;

    

  

    // Update is called once per frame  

    void Update() 

    {

        if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home))

        {

            Application.Quit();

        }

    

  

    IEnumerator openCamera(int whichOne) 

    

        yield return Application.RequestUserAuthorization(UserAuthorization.WebCam); 

        if (Application.HasUserAuthorization(UserAuthorization.WebCam)) 

        

            //可以通过下面的这个数组的索引来选择调用手机上的前置或者后置摄像头,另外这个可以自动对焦

            WebCamDevice[] devices = WebCamTexture.devices;

            if (devices.Length <= whichOne)

            {

                cameraName = devices[0].name;

            }

            else

            {

                cameraName = devices[whichOne].name;

                if (whichOne > 0)

                {

                    Quaternion temp = uiCameraTexture.transform.localRotation;

                    temp.eulerAngles = new Vector3(0, 0, 90);

                    uiCameraTexture.transform.localRotation = temp;

                }

            }

            cameraTexture = new WebCamTexture(cameraName, Screen.width, Screen.height,15);

            cameraTexture.anisoLevel = 9;

            float heightRate = Screen.height / cameraTexture.height;

            float widthRate = Screen.width / cameraTexture.width;

            //Debug.Log(heightRate.ToString());

            //Debug.Log(widthRate.ToString());

            zoomRate = heightRate > widthRate ? heightRate : widthRate;

            if (zoomRate > 2)

            {

                zoomRate = 2;

            }

            cameraTexture.Play();

            

            isPlay = true

        

    

  

    void OnGUI() 

    

        if (isPlay) 

        {

            uiCameraTexture.mainTexture = cameraTexture;

            //NGUIDebug.Log(" cameraTexture.height:" + cameraTexture.height.ToString() + "cameraTexture.width:" + cameraTexture.width.ToString());

            uiCameraTexture.width = cameraTexture.width ;

            uiCameraTexture.height = cameraTexture.height;

            uiCameraTexture.transform.localScale = new Vector3(zoomRate, zoomRate, zoomRate);

            

        }

        if (saved)

        {

//这个逻辑代码的意思就是截图的时候可以不用拍到那个按钮

            ImgBtnTakePictureUISprite.enabled = true;

            ImgBtnTakePictureBoxCollider.enabled = true;

            cameraTexture.Play();

            saved = false;

        }

    }

    void ImgBtnTakePictureOnclik()

    {

        cameraTexture.Pause();

        ImgBtnTakePictureUISprite.enabled = false;

        ImgBtnTakePictureBoxCollider.enabled = false;

        if (!shootSnd.audio.isPlaying)

            shootSnd.audio.Play();

        StartCoroutine(ScreenshotManager.Save("NinthRoomShotAR", "NinthRoom", true));

    }

    void ImgBtnTakePictureOnDoubleclik()

    {

        saved = true;

        cameraTexture.Stop();

        StopAllCoroutines();

        StartCoroutine(openCamera(1));

    }

好了大功告成,一个有模有样的拍照软件就做成了,你可以自主选择相框叠加到里面去,这个都可以根据自己的爱好随意添加。帖子最后我会给出工程文件和插件的下载地址,谢谢你的耐心阅读!如有什么好的建议和任何疑问欢迎回复跟帖!

结合NGUI做的手机拍照(可自定义相框)

时间: 2025-01-03 15:57:47

结合NGUI做的手机拍照(可自定义相框)的相关文章

解决android有的手机拍照后上传图片被旋转的问题

转至 http://blog.csdn.net/walker02/article/details/8211628 需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要把图片上传到服务器 遇到问题:有的手机拍摄的图片旋转90度,有的图片旋转了180度,有的手机是正常的,服务器要求的是正的,这样问题就来了,不能用户发个照片在微博上看到的是被旋转了的啊,另外一个项目里旋转了的图片直接匹配出现问题,这个更严重. 解决:开始的时候在网上没有找到很好的解决办法,谷歌百度的搜

苹果、三星皆躺枪 央视为何曝光手机拍照不合格

苹果.三星又摊上大事了!甚至还顺带着,带跑偏了一众小伙伴.近日,国家照相机质量监督检验中心应浙江省消费者保护委会员要求对9个品牌的10款产品进行了测试.测试发现,10款手机中有8款曝光量准确度误差较大.这8款手机很"和谐"地出现4款国外品牌,4款国内品牌的情况.然而杀伤力却完全不同,苹果和三星是其中的绝对主角. 为何央视<每周质量报告>非得曝光手机拍照不合格的事情?这其中的门道太多,水太深我们无法揣测.不过可以预见的是,这样的事情既不是第一次发生,也不会是最后一次--手机市

部分Android或IOS手机拍照后照片被旋转的问题

1.我们平时手机拍的照片,传到电脑后,使用Photoshop或者其它图片浏览工具打开时,发现图片是被转过的.可是Windows上预览却是正的.其实原因是部分Android或IOS手机拍照后,将图片角度信息存到了Exif信息中.我们只需要读取出来,再做相应的重绘,即可. 2.代码送上. class ImageNormal { public void NormalImageDegree(string imagePath) { var bitmap = (Bitmap)Bitmap.FromFile(

Android开发之手机拍照功能的实现(源代码分享)

Android系统里调用手机拍照的功能有两种方法一种直接调用手机自带的相机另一种就是使用自己做的拍照应用.比如Camera360 一款于各操作系统都有的的功能强大的手机摄影软件:能拍摄出不同风格,不同特效的照片,同时具有云服务和互联网分享功能,全球用户已经超过2.5亿.现在专门的开发一款手机摄影软件肯定没多大意义,已经比不过这些前辈了,我们只需学会如何调用手机自带的摄像机完成拍照并把照片获取过来,为用户提供上传头像,发表图文微博,传送图片的功能即可.完成上述的功能十分的简单,甚至不需要在清单文件

技术指南:手机拍照身份证识别技术

近几年,各种各样的APP正在取代PC端软件成为用户应用方式的首选,而在APP中,用户信息注册是必不可少的环节,尤其是大型公众平台.第三方支付平台.二手车交易平台等,更是有庞大的用户群体来进行信息输入.在这样的大环境中,谁能提供更好的用户体验,谁就会在竞争中抢得先机.因此,基于移动终端的OCR识别技术的延伸应用-手机拍照身份证识别应运而生,解决了APP中用户实名注册过程中的手动录入信息的痛点! 手机拍照身份证识别使用成熟的OCR文字识别技术,通过手机或者带有摄像头的终端设备对身份证拍照,并对证件照

android 手机拍照返回 Intent==null 以及intent.getData==null

手机拍照第一种情况:private void takePicture(){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");String filename = timeStampFormat.format(new Date());ContentValues v

Android使得手机拍照功能的发展(源共享)

Android系统调用手机拍照功能有两种方法来直接调用手机自带摄像头还有一个就是要当心自己的节拍. 例Camera360 强大的一个在每个操作系统都有一个手机摄影软件:您可以捕捉不同风格,不同特效的照片,同一时候具有云服务和互联网分享功能,全球用户已经超过2.5亿.如今专门的开发一款手机摄影软件肯定没多大意义,已经比只是这些前辈了.我们仅仅需学会怎样调用手机自带的摄像机完毕拍照并把照片获取过来,为用户提供上传头像,发表图文微博,传送图片的功能就可以. 完毕上述的功能十分的简单,甚至不须要在清单文

HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

上一篇只讲到前台操作,这篇专门涉及到Java后台处理,前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理,通过对图片数据信息进行Base64解码,之后使用流将图片数据信息上传至服务器进行保存,并且将图片的路径地址存进数据库.ok,废话不多说了,直接贴代码吧. 1.前台js代码: $.ajax({ async:false,//是否异步 cache:false,//是否使用缓存 type: "POST", data:{fileData:fi

android手机拍照或选取相册里面的图片

three.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"