一、以截图形式实现拍照功能:
使用(NGUI)UITexture或者(UGUI)RawImage显示截图,必须提前在场景中创建。
该脚本实现功能:仿照相机界面,竖屏显示,包括返回键、取消键、确认键。
Unity在不调取移动端的情况下实现拍照功能,就必须有WebCamTexture类,如果不理解,请查看博文,
链接:http://blog.csdn.net/it_yanghui/article/details/78615209
下面附上代码:
TakePhoto(以截图形式实现拍照功能)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
public class TakePhoto: TakePhotoBase {
private UIButton[] _btnArr;
private UIButton _backBtn;
private UIButton _ensureBtn;
private UIButton _cancelBtn;
private UITexture cameraTexture; //相机画面(需要提前创建(NGUI)UITexture或者(UGUI)RawImage,用来显示截图)
private WebCamTexture webCameraTexture; //相机贴图(无需赋值)
private byte[] bts = null;
private string photoName = string.Empty; //用于保存本地使用
protected override void OnAwake()
{
base.OnAwake();
if (null == _instance)
_instance = this;
}
protected override void OnStart()
{
base.OnStart();
Init();
photoName = "touxiang";
}
void Init()
{
//设置屏幕正方向在Home键左边
Director.GetInstance.SetGameScreenAutoRotation(ScreenOrientation.LandscapeLeft);
if (null == cameraTexture)
cameraTexture = GetComponentInChildren();
_btnArr = GetComponentsInChildren();
for (int i= 0; i < _btnArr.Length; i++)
{
InitBtn(_btnArr[i]);
UIEventListener.Get(_btnArr[i].gameObject).onClick = delegate (GameObject go)
{
ClickCallBack(go);
};
}
ShowBtnCtr(true, false);//显示返回按钮
StartCoroutine(StartCamera());//开启相机
}
//初始化按钮
private void InitBtn(UIButton btn)
{
switch (btn.name)
{
case "Btn_Back":
_backBtn = btn;
break;
case "Btn_Ensure":
_ensureBtn = btn;
break;
case "Btn_Cancel":
_cancelBtn = btn;
break;
default:
break;
}
}
private void ClickCallBack(GameObject go)
{
string btnName = go.name;
switch (btnName)
{
case "Btn_TakePhoto":
StartCoroutine(GetTexture());//截图
ShowBtnCtr(false, true);//显示确认按钮
break;
case "Btn_Back":
CloseCamera();
break;
case "Btn_Ensure":
string str1 = "file";
if (bts != null)
StartCoroutine(ServiceMgr.GetInstance.UploadingTexture(Global_Game.postUrl_FileUploading, str1, bts));//上传截图(或者其他操作)
break;
case "Btn_Cancel":
if (bts != null)
bts = null;
if (webCameraTexture != null)
{
webCameraTexture.Play();
}
else
{
StartCoroutine(StartCamera());
}
ShowBtnCtr(true, false);//显示返回按钮
break;
default:
break;
}
}
IEnumerator StartCamera()//调用移动端相机
{
int maxl = Screen.width;
if (Screen.height > Screen.width) { maxl = Screen.height; }
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
WebCamDevice[] devices = WebCamTexture.devices;
string devicename = devices[0].name;
webCameraTexture = new WebCamTexture(devicename, maxl, maxl, 12);
webCameraTexture.wrapMode = TextureWrapMode.Repeat;
cameraTexture.mainTexture = webCameraTexture;
webCameraTexture.Play();
}
}
IEnumerator GetTexture()//获取截图
{
yield return new WaitForEndOfFrame();
Texture2D tex = new Texture2D(cameraTexture.width, cameraTexture.height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, cameraTexture.width, cameraTexture.height), 0, 0, true);
tex.Apply();
byte[] bt = tex.EncodeToPNG();
bts = new byte[bt.Length];
bts = bt;
webCameraTexture.Stop();
}
///
/// 关闭相机画面
///
public void CloseCamera()
{
if(webCameraTexture != null)
webCameraTexture.Stop();
//设置屏幕可以左右旋转
Director.GetInstance.SetGameScreenAutoRotation(ScreenOrientation.AutoRotation);
}
///
/// 控制按钮显示或隐藏
///
///
///
private void ShowBtnCtr(bool backBtnIsShow ,bool otherIsShow)
{
if (null == _backBtn || null == _ensureBtn || null == _cancelBtn)
return;
_backBtn.gameObject.SetActive(backBtnIsShow);
_ensureBtn.gameObject.SetActive(otherIsShow);
_cancelBtn.gameObject.SetActive(otherIsShow);
}
}
注意:1.android包名要和unity保持一致
2.unitygameobjectName要对应
3.须将unity下的classes.jar拷贝至安卓工程libs下方可正确编译再导出为jar包,classes.jar 地址:
在Unity安装路径Editor下:在Unity图标右键点击打开文件位置,找到以下路径classes.jar 包,
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
建立工程之后,要将res下layout文件下.xml文件删除,因为不需要使用安卓布局。
详细介绍(包括打包导出jar包):之前博文:Unity5与Android交互通信(使用Android Studio2.4)
链接:http://blog.csdn.net/it_yanghui/article/details/78490599
安卓代码:MainActivity.java
package com.xxx.xxx; //对应unity的包名
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends UnityPlayerActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PHOTO_REQUEST_CODE = 1;//相册
public static final int PHOTOHRAPH = 2;// 拍照
private static final boolean DEBUG = false;
private String unitygameobjectName = "PersonInfo"; //Unity 中对应挂脚本对象的名称
public static final int NONE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//强制设置屏幕方向(根据自己需要)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
//调用相机
public void takephoto(){
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intent, PHOTOHRAPH);
}
//调用相册
public void OpenGallery()
{
Intent intent = new Intent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent, PHOTO_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == NONE){
return;
}
if(PHOTO_REQUEST_CODE == requestCode){//相册
if(data == null){
return;
}
Uri uri = data.getData();
String imagePath = getImagePath(uri);
if(DEBUG){
Log.d(TAG, imagePath);
}
//调用unity中方法 GetImagePath(imagePath)
UnityPlayer.UnitySendMessage(unitygameobjectName, "GetImagePath", imagePath);
}
if (requestCode == PHOTOHRAPH) {//相机
String path = Environment.getExternalStorageDirectory() + "/temp.jpg";
if(DEBUG){
Log.e("path:", path);
}
//调用unity中方法 GetImagePath(path)
UnityPlayer.UnitySendMessage(unitygameobjectName, "GetImagePath", path);
try {
Bitmap bitmap = BitmapFactory.decodeFile(path);
SaveBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getImagePath(Uri uri)
{
if(null == uri) return null;
String path = null;
final String scheme = uri.getScheme();
if (null == scheme) {
path = uri.getPath();
} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
path = uri.getPath();
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(uri, proj, null, null,
null);
int nPhotoColumn = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (null != cursor) {
cursor.moveToFirst();
path = cursor.getString(nPhotoColumn);
}
cursor.close();
}
return path;
}
public void SaveBitmap(Bitmap bitmap) throws IOException {
FileOutputStream fOut = null;
String path = "/mnt/sdcard/DCIM/";
try {
//查看这个路径是否存在,
//如果并没有这个路径,
//创建这个路径
File destDir = new File(path);
if (!destDir.exists())
{
destDir.mkdirs();
}
String FILE_NAME = System.currentTimeMillis() + ".jpg";
fOut = new FileOutputStream(path + "/" + FILE_NAME) ;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//将Bitmap对象写入本地路径中
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
AndroidManifest.xml:该文件下不能有注释,拷贝代码后,把注释删掉。
android:versionCode="1"
android:versionName="1.0" >
android:targetSdkVersion="23" />
android:icon="@drawable/app_icon"//此处是在res下的图标资源(用于显示apk图标)
android:label="xxx"//Library名
android:supportsRtl="true">
android:screenOrientation="landscape">//此处是限制屏幕只能竖屏
Unity 代码:TakePhoto .cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TakePhoto : MonoBehaviour {
// Use this for initialization
void Start()
{
}
//打开相册
public void OpenPhoto()
{
//这三句代码是不变的,只管用就行了(引号内是Andriod端Activity内部方法名)
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic
jo.Call("OpenGallery");
}
//打开相机
public void OpenCamera()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic
jo.Call("takephoto");
}
//获取图片安卓路径
public void GetImagePath(string imagePath)
{
if (!string.IsNullOrEmpty(imagePath))
{
StartCoroutine(LoadImage(imagePath));
}
}
//获取图片
private IEnumerator LoadImage(string imagePath)
{
WWW www = new WWW("file://" + imagePath);
yield return www;
if (string.IsNullOrEmpty(www.error))
{
//成功读取图片,写自己的逻辑
//上传图片
byte[] bts = www.texture.EncodeToPNG();
if (bts != null)
StartCoroutine(ServiceMgr.GetInstance.UploadingTexture(Global_Game.postUrl_FileUploading, "file", bts));
//释放资源
www.Dispose();
}
else
{
Debug.LogError("LoadImage>>>www.error:" + www.error);
}
}
}