Unity3d本地上传并且裁剪图片-----Android平台

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的博客之后添加

你可能感兴趣的:(unity3d)