unity 启动相机_Unity3D研究院之打开照相机与本地相册进行裁剪显示(三十三)...-程序员宅基地

技术标签: unity 启动相机  

最近做项目需要用到这个功能,就是在Unity中调用Android本地相册或直接打开摄像机拍照并且裁剪一部分用于用户头像,今天研究了一下,那么研究出成果了MOMO一定要分享给大家。Unity与Android的交互还有谁不会?? 如果有不会的朋友请看MOMO之前的文章喔,Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)这里有关交互的方式就不详细说明,主要将如何在Unity中打开摄像机、在Unity中打开本地相册,选一个照片后如何进行裁剪,最后将图片转换成Texture显示在U3D的世界当中。

首先看看Eclipse中的Android插件部分,我的包名是com.xys请大家与MOMO保持一致,Unity工程中也需要是这个包名噢。

UnityTestActivity.java 这个类是Unity的插件主类,在这里调用是打开摄像机 还是本地相册的方法。

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

packagecom.xys;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.os.Bundle;

importcom.unity3d.player.UnityPlayerActivity;

publicclassUnityTestActivityextendsUnityPlayerActivity{

//public class UnityTestActivity extends Activity {

ContextmContext=null;

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

mContext=this;

}

//Unity中会调用这个方法,用于区分打开摄像机 开始本地相册

publicvoidTakePhoto(Stringstr)

{

Intentintent=newIntent(mContext,WebViewActivity.class);

intent.putExtra("type",str);

this.startActivity(intent);

}

}

然后是WebViewActivity.java 这里主要处理用户打开摄像机或本地相册后如何进行裁剪图片,并且把裁剪的图片储存在本地文件中。

C#

1

2

3

4

5

6

7

8

9

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

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

packagecom.xys;

importjava.io.File;

importjava.io.FileNotFoundException;

importjava.io.FileOutputStream;

importjava.io.IOException;

importcom.unity3d.player.UnityPlayer;

importandroid.app.Activity;

importandroid.content.Intent;

importandroid.graphics.Bitmap;

importandroid.net.Uri;

importandroid.os.Bundle;

importandroid.os.Environment;

importandroid.provider.MediaStore;

importandroid.view.KeyEvent;

importandroid.widget.ImageView;

publicclassWebViewActivityextendsActivity

{

ImageViewimageView=null;

publicstaticfinalintNONE=0;

publicstaticfinalintPHOTOHRAPH=1;// 拍照

publicstaticfinalintPHOTOZOOM=2;// 缩放

publicstaticfinalintPHOTORESOULT=3;// 结果

publicstaticfinalStringIMAGE_UNSPECIFIED="image/*";

publicfinalstaticStringFILE_NAME="image.png";

publicfinalstaticStringDATA_URL="/data/data/";

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

imageView=(ImageView)this.findViewById(R.id.imageID);

Stringtype=this.getIntent().getStringExtra("type");

//在这里判断是打开本地相册还是直接照相

if(type.equals("takePhoto"))

{

Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);

intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(newFile(Environment.getExternalStorageDirectory(),"temp.jpg")));

startActivityForResult(intent,PHOTOHRAPH);

}else

{

Intentintent=newIntent(Intent.ACTION_PICK,null);

intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,IMAGE_UNSPECIFIED);

startActivityForResult(intent,PHOTOZOOM);

}

}

@Override

protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){

if(resultCode==NONE)

return;

// 拍照

if(requestCode==PHOTOHRAPH){

//设置文件保存路径这里放在跟目录下

Filepicture=newFile(Environment.getExternalStorageDirectory()+"/temp.jpg");

startPhotoZoom(Uri.fromFile(picture));

}

if(data==null)

return;

// 读取相册缩放图片

if(requestCode==PHOTOZOOM){

startPhotoZoom(data.getData());

}

// 处理结果

if(requestCode==PHOTORESOULT){

Bundleextras=data.getExtras();

if(extras!=null){

Bitmapphoto=extras.getParcelable("data");

imageView.setImageBitmap(photo);

try{

SaveBitmap(photo);

}catch(IOExceptione){

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

super.onActivityResult(requestCode,resultCode,data);

}

publicvoidstartPhotoZoom(Uriuri){

Intentintent=newIntent("com.android.camera.action.CROP");

intent.setDataAndType(uri,IMAGE_UNSPECIFIED);

intent.putExtra("crop","true");

// aspectX aspectY 是宽高的比例

intent.putExtra("aspectX",1);

intent.putExtra("aspectY",1);

// outputX outputY 是裁剪图片宽高

intent.putExtra("outputX",300);

intent.putExtra("outputY",300);

intent.putExtra("return-data",true);

startActivityForResult(intent,PHOTORESOULT);

}

publicvoidSaveBitmap(Bitmapbitmap)throwsIOException{

FileOutputStreamfOut=null;

//注解1

Stringpath="/mnt/sdcard/Android/data/com.xys/files";

try{

//查看这个路径是否存在,

//如果并没有这个路径,

//创建这个路径

FiledestDir=newFile(path);

if(!destDir.exists())

{

destDir.mkdirs();

}

fOut=newFileOutputStream(path+"/"+FILE_NAME);

}catch(FileNotFoundExceptione){

e.printStackTrace();

}

//将Bitmap对象写入本地路径中,Unity在去相同的路径来读取这个文件

bitmap.compress(Bitmap.CompressFormat.PNG,100,fOut);

try{

fOut.flush();

}catch(IOExceptione){

e.printStackTrace();

}

try{

fOut.close();

}catch(IOExceptione){

e.printStackTrace();

}

}

@Override

publicbooleanonKeyDown(intkeyCode,KeyEventevent)

{

if(keyCode==KeyEvent.KEYCODE_BACK&&event.getRepeatCount()==0)

{

//当用户点击返回键是 通知Unity开始在"/mnt/sdcard/Android/data/com.xys/files";路径中读取图片资源,并且现在在Unity中

UnityPlayer.UnitySendMessage("Main Camera","message",FILE_NAME);

}

returnsuper.onKeyDown(keyCode,event);

}

}

注解1:主要是路径”/mnt/sdcard/Android/data/com.xys/files”,如下图所示,我们在这里把文件保存在这个路径下。为什么要把图片2进制文件写在这里呢? 还记得以前MOMO给大家说过在Unity中访问Android或IOS本地2进制文件时用到的这个路径,

Application.persistentDataPath   该路径等价于 /mnt/sdcard/Android/data/com.xys/files ,当然后者的包名是对应的工程包名,这样在Unity中可以找到对应裁剪后的图片文件,并且显示在Unity中。

AndroidManifest.xml  这个文件也没什么好说的,大家看看吧。

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

package="com.xys"

android:versionCode="1"

android:versionName="1.0">

android:icon="@drawable/ic_launcher"

android:label="@string/app_name">

android:name=".UnityTestActivity"

android:label="@string/app_name">

android:name=".WebViewActivity">

然后把上面的Android工程打包做成插件放在Unity中。如下图所示,这个我的Unity工程中对应的路径。如果看不懂的朋友请看我之前的文章哈。

然后看Test.cs脚本,它直接挂在摄像机身上。

C#

1

2

3

4

5

6

7

8

9

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

62

63

64

65

66

67

68

69

usingUnityEngine;

usingSystem.Collections;

usingSystem.IO;

publicclassTest:MonoBehaviour

{

publicGUISkinskin;

Texturetexture;

voidUpdate()

{

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

{

Application.Quit();

}

}

voidOnGUI()

{

GUI.skin=skin;

if(GUILayout.Button("打开手机相册"))

{

//调用我们制作的Android插件打开手机相册

AndroidJavaClassjc=newAndroidJavaClass("com.unity3d.player.UnityPlayer");

AndroidJavaObjectjo=jc.GetStatic("currentActivity");

jo.Call("TakePhoto","takeSave");

}

if(GUILayout.Button("打开手机摄像机"))

{

//调用我们制作的Android插件打开手机摄像机

AndroidJavaClassjc=newAndroidJavaClass("com.unity3d.player.UnityPlayer");

AndroidJavaObjectjo=jc.GetStatic("currentActivity");

jo.Call("TakePhoto","takePhoto");

}

if(texture!=null)

{

//注意! 我们在这里绘制Texture对象,该对象是通过

//我们制作的Android插件得到的,当这个对象不等于空的时候

//直接绘制。

GUI.DrawTexture(newRect(100,300,300,300),texture);

}

}

voidmessgae(stringstr)

{

//在Android插件中通知Unity开始去指定路径中找图片资源

StartCoroutine(LoadTexture(str));

}

IEnumeratorLoadTexture(stringname)

{

//注解1

stringpath="file://"+Application.persistentDataPath+"/"+name;

WWWwww=newWWW(path);

while(!www.isDone)

{

}

yieldreturnwww;

//为贴图赋值

texture=www.texture;

}

}

注解1:请大家一定要注意这个路径的写法, 前面一定要加 “File://” 不然无法读取。OK说了这么多我们看看这个项目运行的效果,激动人心的时刻来临啦 嚯嚯嚯嚯!!!

1.首次进入的画面, 这里的图片是我刚刚从相册选择的

2.打开相册我们选择一张图片

3. 选择一张图片,我们进行裁剪

最后我们返回到Unity中界面。新的图片Unity已经完成读取,界面上已经修改成刚刚我裁剪的啦,哇咔咔。 怎么样,还不错啦? 哈哈后。这个做用户头像肯定给力 蛤蛤。

如果点击打开摄像机按钮,拍照完毕后会提示裁剪,裁减完毕返回到Unity界面中同样能看到效果。

最后MOMO将本篇博文的源码放出来,  源码包括Android的工程 与Unity的工程,雨松MOMO祝大家学习愉快,大家互相学习互相进步,加油哇咔咔,啦啦啦。

最后编辑:2015-07-03作者:雨松MOMO

专注移动互联网,Unity3D游戏开发

捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39548541/article/details/112023468

智能推荐

学习笔记----周志华《机器学习》第五章(神经网络)(一)_(1)请参考下面的参考资料(来自周志华教程),对一个最简单的三层神经网络(一个隐含-程序员宅基地

文章浏览阅读434次。周志华的《机器学习》算作一本入门的宝书。本文是对周志华的机器学习第五章神经网络的学习笔记。在第五章主要涉及的内容:神经网络、常见激活函数、感知机、多层前馈神经网络 、反向传播算法(BP算法)、全局最小和局部极小、其他神经网络(RBF、ART、SOM等网络)、递归神经网络(如Boltzmann机、Elman网络)。如果哪里有不对的地方,请不吝指点!一、什么是神经网络? 关于神经网络的定义有很多,本文对于神经网络的定义:神经网络是由具有适应性的简单单元(实际上是神经元)组成的广泛并且互联..._(1)请参考下面的参考资料(来自周志华教程),对一个最简单的三层神经网络(一个隐含

制作一个3D旋转相册_动感立体旋转相册制作-程序员宅基地

文章浏览阅读531次。利用HTML常用标签,CSS常用属性,JS入门语法制作一个3D旋转相册part one完成《个人相册》项目登录页面代码如下:_动感立体旋转相册制作

mysql 常用命令(二)_ln -s full-path-to-mysql-version-os mysql-程序员宅基地

文章浏览阅读375次。mysql_ln -s full-path-to-mysql-version-os mysql

进制转换(二进制,八进制,十进制,十六进制)_八进制转十六进制-程序员宅基地

文章浏览阅读636次,点赞3次,收藏4次。二进制转八进制,十六进制;二进制转十进制,N进制转十进制,十进制转二进制,十进制转N进制_八进制转十六进制

java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectWriter.forType-程序员宅基地

文章浏览阅读1.5w次。异常信息:java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.ObjectWriter.forType(Lcom/fasterxml/jackson/databind/JavaType;)Lcom/fasterxml/jackson/databind/ObjectWriter; at org.springframew_java.lang.nosuchmethoderror: com.fasterxml.jackson.databind.objectmapper.act

MATLAB 直角坐标系与极坐标系相互转换_matlab直角坐标系转换极坐标-程序员宅基地

文章浏览阅读1.4k次。thera范围为[-pi, pi]弧度转度数:thera/pi180*_matlab直角坐标系转换极坐标

随便推点

怎么恢复删除的照片?分享5种恢复 iPhone /iPad 照片的方法_ios删除的照片怎么找回 csdn-程序员宅基地

文章浏览阅读2.9k次。从 iPhone 中删除照片可能会带来压力。以下是如何使用几种不同的方法从 iPhone 恢复最近删除的照片。运气好的话,如果照片没有被新数据覆盖,您可以取回照片。方法 1. 使用iPhone照片恢复工具方法 2. 没有软件的情况下方法 3. 从 iPhone 备份方法 4. 从 iTunes 备份方法 5。 从 iCloud 备份_ios删除的照片怎么找回 csdn

Java23种设计模式——20.行为型模式之迭代器模式-程序员宅基地

文章浏览阅读935次。Java中除去有设计原则之外,还有23中设计模式。这些模式都是前辈们一点一点积累下来,一直在改进,一直在优化的,而这些设计模式可以解决一些特定的问题。并且在这些模式中,可以说是将语言的使用体现的淋漓尽致。那我们今天要学习行为型模式中的迭代器模式 !迭代器模式先来百科一下,什么是迭代器模式这个其实和我们在遍历 List、Set集合时候使用的迭代器类似,我们在不暴露对象的内部,就可以遍历该集合模式的定义与特点迭代器(Iterator)模式的定义:提供一个对象来顺...

My97 DatePicker——强大的 JavaScript 日历控件_my97datepicker源码 js-程序员宅基地

文章浏览阅读708次。 My97 DatePicker最新版本: 4.0 Release 2008-05-30在线演示Blog1: CnblogsBlog2: CSDN 技术支持下载官网[修正]被其他页面引入时,有跨域错误的问题[修正]平面显示时,点击其他地方下拉框不会自动消失[修正]平面模式在多框架情况下跳转时有时不显示的问题[修正]在极少数的情况下,由于预载失败导致选择框不能弹出的问题_my97datepicker源码 js

安卓(雷电)模拟器清除屏幕密码[亲测可用]_雷电模拟器突然有密码解锁-程序员宅基地

文章浏览阅读1k次,点赞9次,收藏12次。(2)正确做法是重命名 lockset 开头的文件,上图只找到locksettings.db文件,因此重命名该文件即可;(1)遇到这种情况说明模拟器自带的 adb.exe 程序不兼容,需要替换为android sdk自带的adb.exe;命令删除所有key文件,如上图蓝框内容,没找到key文件,如果有对应key文件直接删除也会有其他错误出现;(1)所在文件夹的路径中,清除路径内容,输入。(1)很多转载文要求,进入。_雷电模拟器突然有密码解锁

加速ASP.NET Core WEB API应用程序。 第三部分-程序员宅基地

文章浏览阅读283次。深度重构和完善ASP.NET Core WEB API应用程序代码 (Deep refactoring and refinement of ASP.NET Core WEB API application code) 介绍 (Introduction)Part 1. Creating a test RESTful WEB API application. 第1部分。创建一个测试RESTf..._netco加速

【hibernate框架】一对一双向外键关联(Annotation实现)-程序员宅基地

文章浏览阅读81次。一对一双向外键关联(Annotation方法):一夫(Husband)一妻(Wife)的一对一双向外键关联Husband和Wife实体类:package cn.edu.hpu.one2one;import javax.persistence.Entity;import javax.persistence.GeneratedValue;im..._一对一双向外键

推荐文章

热门文章

相关标签