Unity3d本地上传并且裁剪图片-----Android平台
注:引擎版本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的博客之后添加