注:引擎版本unity4.x
最近项目需求,需要做用户头像,要求:
1. 可以从本地上传
2. 本地裁剪
3. 压缩控制大小
4. 在三个平台实现PC/Android/IOS
弄了好几天总是搞完了总结一下
从本地上传会用到Android系统功能,打开相册和用摄像机拍照,因此unity和Android的交互是必须要会的。
Unity-android可参考到宣雨松的博客http://www.xuanyusong.com/archives/676package com.cheerflame.sdrn;
我参考过一些博文之后整理了一个图片处理类,直接导入这个类调用它的方法就可以了
用法(3步):
1.//在MainActivity中创建图片处理对象
ImgManage = new HeadImgManage(this);
2.//在unity中调用此接口,在接口中调用图片处理类的TakePhoto方法,当choose = 0 的时候打开相机拍照,choose=1的时候打开相册
public void TakePhoto(int choose){
ImgManage.TakePhoto(choose);
}
3.//在MainActivity中接收事件请求回调
protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.i("TEST", "requestCode = " + requestCode); if (resultCode == NONE){ Log.i("TEST", "resultCode == NONE "); return; } if (requestCode == PHOTOHRAPH) { Log.i("TEST", "拍照完成"); File picture = new File(Environment.getExternalStorageDirectory() + "/temp.jpg"); ImgManage.startPhotoZoom(Uri.fromFile(picture)); } if (data == null) { Log.i("TEST", "data == null"); return; } // 读取相册缩放图片 if (requestCode == PHOTOZOOM) { Log.i("TEST", "读取相册完成"); ImgManage.startPhotoZoom(data.getData()); } // 处理结果 if (requestCode == PHOTORESOULT) { Bundle extras = data.getExtras(); if (extras != null) { Bitmap photo = extras.getParcelable("data"); try { ImgManage.SaveBitmap(photo); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } super.onActivityResult(requestCode, resultCode, data); }
处理类:
package com.cheerflame.sdrn; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; public class HeadImgManage{ UnityPlayerActivity unityActivity; public static final int NONE = 0; public static final int PHOTOHRAPH = 1;// 拍照 public static final int PHOTOZOOM = 2; // 缩放 public static final int PHOTORESOULT = 3;// 结果 public static final String IMAGE_UNSPECIFIED = "image/*"; public final static String FILE_NAME = "image.jpg"; public final static String DATA_URL = "/data/data/"; public HeadImgManage(UnityPlayerActivity activity){ unityActivity = activity; } public void TakePhoto(int choose) { if(choose == 0) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg"))); unityActivity.startActivityForResult(intent, PHOTOHRAPH); } else { Intent intent = new Intent(Intent.ACTION_PICK, null); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED); unityActivity.startActivityForResult(intent, PHOTOZOOM); } } public void startPhotoZoom(Uri uri) { Log.i("TEST", "开始裁剪" + uri); Intent intent = new Intent("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); unityActivity.startActivityForResult(intent, PHOTORESOULT); } public void SaveBitmap(Bitmap bitmap) throws IOException { Log.i("TEST", "保存文件"); FileOutputStream fOut = null; //注解 String path = "/mnt/sdcard/Android/data/com.cheerflame.sdrn/files"; try { //查看这个路径是否存在, //如果并没有这个路径, //创建这个路径 File destDir = new File(path); if (!destDir.exists()) { destDir.mkdirs(); } fOut = new FileOutputStream(path + "/" + FILE_NAME) ; Log.i("TEST", "保存路径:" + path + "/" + FILE_NAME); UnityPlayer.UnitySendMessage("Camera", "HeadImage","success!"); Log.i("TEST", "success"); } catch (FileNotFoundException e) { e.printStackTrace(); } //将Bitmap对象写入本地路径中,Unity在去相同的路径来读取这个文件 bitmap.compress(Bitmap.CompressFormat.JPEG, 10, fOut); try { fOut.flush(); } catch (IOException e) { e.printStackTrace(); } try { fOut.close(); } catch (IOException e) { e.printStackTrace(); } } }
"/mnt/sdcard/Android/data/com.xxxx.xxx/files"目录和unity中UnityEngine.Application.persistentDataPath获得路径是一样的,也就是沙盒文件,对沙盒文件操作网上介绍蛮多,我这里就不多说了
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, fOut);这个参数10,是0-100选取图片质量的函数,一般从相册截取完图片之后,图片大小大约是30-40k,显然太大了,10的话大约压缩到原来的1/10,也就是3-4k就很小了
ios的博客之后添加