cocos2d-x与Android混编实现换“头像图片”
2014-04-02 15:02
471 查看
最近接手玩家个性化功能,其中较难处理就是更换玩家的“头像”操作。通过努力搜索,终于找到解决方案了。 若更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取,裁剪图片,裁剪完成往服务器上传图片功能,从而达到换用户头像的操作的功能; 那么,就要通过用JniHelper 去调用 andriod java里面的类和方法,实现混编来满足我们操作android系统的各种需求,如:获取本机MAC地址,获取本机名称,甚至还可去操作android后台服务的复杂操作了; 言归正传,我们需要编写android 的Activity类,这个类主要功能就是 调用android本地图片,选取,裁剪,裁剪玩往服务器上传图片;先看一下我的目录结构:
userinfo.xml视图文件的UI:
android平台,游戏入口Cocos2dxActivity(GuideLayer),如下:public class GuideLayer extends Cocos2dxActivity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// GuideLayer should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
static {
System.loadLibrary("cocos2dcpp");
}
//执行android的页面跳转,跳转的我的功能类UserInfoActivity.java;
public static Object gotoActivity()
{
Intent in = new Intent(GuideLayer.getContext(),UserInfoActivity.class);
GuideLayer.getContext().startActivity(in);
return null;
}
} 这是一个静态类;返回类型为Object,但是我不需要返回值,因为我执行页面跳转,那如果我的需求是获取android模块代码的值,就可以填写对应的返回类型,就可以进行java和c++的相互传值;
处理更换头像功能:UserInfoActivity.javapackage com.GuideLayer.org;
import java.io.ByteArrayOutputStream;
import java.io.File;
import com.GuideLayer.org.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UserInfoActivity extends Activity {
private ImageButton user_nan, user_nv;
private TextView ut_nan, ut_nv,tv_usernumber,tv_jinbi,tv_jindou,tv_zhanji,tv_shenglv;
private LinearLayout lf;
private ImageView user_headImage;
private ImageButton save_bc;
private static final int REQUEST_CODE_GETIMAGE_BYSDCARD = 0;// 从sd卡得到图像的请求码
private static final int REQUEST_CODE_GETIMAGE_BYCAMERA = 1;// 从相机得到图像的请求码
private String thisLarge = null, theSmall = null;
private byte[] picture2;
//用户信息
private EditText editText1;
private String nowsex="男";
Thread td_into;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 窗体状态设置-设置为无标题栏状态【全屏】
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.userinfo);
lf.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CharSequence[] items = { "手机相册", "手机拍照", "取消" };
imageChooseItem(items);
}
});
}
/**
* 操作选择
*
* @param items
*/
public void imageChooseItem(CharSequence[] items) {
AlertDialog imageDialog = new AlertDialog.Builder(this)
.setTitle("增加图片")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
// 手机选图
Intent intent = new Intent(
Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent,
REQUEST_CODE_GETIMAGE_BYSDCARD);
}
// 拍照
else if (item == 1) {
Intent intentC = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentC.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(
Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intentC, REQUEST_CODE_GETIMAGE_BYCAMERA);
}
}
}).create();
imageDialog.show();
}
// 获取图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_GETIMAGE_BYSDCARD) {
Bitmap bitm = null;
if (data != null) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
final Intent intent1 = new Intent(
"com.android.camera.action.CROP");
intent1.setDataAndType(selectedImage, "image/*");
intent1.putExtra("crop", "true");
intent1.putExtra("aspectX", 1);
intent1.putExtra("aspectY", 1);
intent1.putExtra("outputX", 235);
intent1.putExtra("outputY", 235);
intent1.putExtra("return-data", true);
startActivityForResult(intent1, 4);
}
}
if(bitm!=null){
user_headImage
.setImageDrawable(new BitmapDrawable(this.getResources(),bitm));
}
}
// 拍摄图片
else if (requestCode == REQUEST_CODE_GETIMAGE_BYCAMERA) {
if (resultCode != RESULT_OK) {
return;
}
// 设置文件保存路径这里放在跟目录下
File picture = new File(Environment.getExternalStorageDirectory()
+ "/temp.jpg");
startPhotoZoom(Uri.fromFile(picture));
} else if (requestCode == 4) {
if (data != null){
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageDrawable(new BitmapDrawable(this
.getResources(), bmp));
}
}
else if (requestCode == 5) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageBitmap(bmp);
}
}
}
public static final String IMAGE_UNSPECIFIED = "image/*";
public void startPhotoZoom(Uri uri) {
System.out.println(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", 235);
intent.putExtra("outputY", 235);
intent.putExtra("return-data", true);
startActivityForResult(intent, 5);
}
public void saveok() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
public void saveno() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
} 因为我们调用的是android系统头像,需要用到照相功能,所以还的开启这个功能权限;在AndroidManifest.xml中添加如下代码: <uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.READ_LOGS"/> 还有一个类,的activity的配置:
ok,转到win32平台: 在HelloWorldScene.cpp,引入:#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#if 1
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
#endif 触发跳转代码:
各位网友,请记住这货:http://www.cnblogs.com/zisou/p/cocos2dxJQ.html 相关图片资源,源码下载地址:http://pan.baidu.com/share/link?shareid=1525180823&uk=4097703620&third=15
userinfo.xml视图文件的UI:
android平台,游戏入口Cocos2dxActivity(GuideLayer),如下:public class GuideLayer extends Cocos2dxActivity{
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// GuideLayer should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
static {
System.loadLibrary("cocos2dcpp");
}
//执行android的页面跳转,跳转的我的功能类UserInfoActivity.java;
public static Object gotoActivity()
{
Intent in = new Intent(GuideLayer.getContext(),UserInfoActivity.class);
GuideLayer.getContext().startActivity(in);
return null;
}
} 这是一个静态类;返回类型为Object,但是我不需要返回值,因为我执行页面跳转,那如果我的需求是获取android模块代码的值,就可以填写对应的返回类型,就可以进行java和c++的相互传值;
处理更换头像功能:UserInfoActivity.javapackage com.GuideLayer.org;
import java.io.ByteArrayOutputStream;
import java.io.File;
import com.GuideLayer.org.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class UserInfoActivity extends Activity {
private ImageButton user_nan, user_nv;
private TextView ut_nan, ut_nv,tv_usernumber,tv_jinbi,tv_jindou,tv_zhanji,tv_shenglv;
private LinearLayout lf;
private ImageView user_headImage;
private ImageButton save_bc;
private static final int REQUEST_CODE_GETIMAGE_BYSDCARD = 0;// 从sd卡得到图像的请求码
private static final int REQUEST_CODE_GETIMAGE_BYCAMERA = 1;// 从相机得到图像的请求码
private String thisLarge = null, theSmall = null;
private byte[] picture2;
//用户信息
private EditText editText1;
private String nowsex="男";
Thread td_into;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// 窗体状态设置-设置为无标题栏状态【全屏】
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 强制横屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.userinfo);
lf.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
CharSequence[] items = { "手机相册", "手机拍照", "取消" };
imageChooseItem(items);
}
});
}
/**
* 操作选择
*
* @param items
*/
public void imageChooseItem(CharSequence[] items) {
AlertDialog imageDialog = new AlertDialog.Builder(this)
.setTitle("增加图片")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
// 手机选图
Intent intent = new Intent(
Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent,
REQUEST_CODE_GETIMAGE_BYSDCARD);
}
// 拍照
else if (item == 1) {
Intent intentC = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentC.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(
Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intentC, REQUEST_CODE_GETIMAGE_BYCAMERA);
}
}
}).create();
imageDialog.show();
}
// 获取图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_GETIMAGE_BYSDCARD) {
Bitmap bitm = null;
if (data != null) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
final Intent intent1 = new Intent(
"com.android.camera.action.CROP");
intent1.setDataAndType(selectedImage, "image/*");
intent1.putExtra("crop", "true");
intent1.putExtra("aspectX", 1);
intent1.putExtra("aspectY", 1);
intent1.putExtra("outputX", 235);
intent1.putExtra("outputY", 235);
intent1.putExtra("return-data", true);
startActivityForResult(intent1, 4);
}
}
if(bitm!=null){
user_headImage
.setImageDrawable(new BitmapDrawable(this.getResources(),bitm));
}
}
// 拍摄图片
else if (requestCode == REQUEST_CODE_GETIMAGE_BYCAMERA) {
if (resultCode != RESULT_OK) {
return;
}
// 设置文件保存路径这里放在跟目录下
File picture = new File(Environment.getExternalStorageDirectory()
+ "/temp.jpg");
startPhotoZoom(Uri.fromFile(picture));
} else if (requestCode == 4) {
if (data != null){
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageDrawable(new BitmapDrawable(this
.getResources(), bmp));
}
}
else if (requestCode == 5) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap bmp = data.getParcelableExtra("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 75, stream);//
picture2 = stream.toByteArray();
user_headImage.setImageBitmap(bmp);
}
}
}
public static final String IMAGE_UNSPECIFIED = "image/*";
public void startPhotoZoom(Uri uri) {
System.out.println(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", 235);
intent.putExtra("outputY", 235);
intent.putExtra("return-data", true);
startActivityForResult(intent, 5);
}
public void saveok() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
public void saveno() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
} 因为我们调用的是android系统头像,需要用到照相功能,所以还的开启这个功能权限;在AndroidManifest.xml中添加如下代码: <uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.READ_LOGS"/> 还有一个类,的activity的配置:
<activity android:name="com.xxx.xxxxx.UserInfoActivity"></activity>
ok,转到win32平台: 在HelloWorldScene.cpp,引入:#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#if 1
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
#endif 触发跳转代码:
void HelloWorld::menuCloseCallback(CCObject* pSender) { CCLog("玩家点击头像换头像了"); #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo minfo; jobject jobj; //getStaticMethodInfo方法是调用静态类的,也可以不用调用静态类的getMethodInfo bool b = JniHelper::getStaticMethodInfo(minfo, "com.GuideLayer.org.GuideLayer", //类路径 "gotoActivity", //静态方法名 "()Ljava/lang/Object;"); //括号里的是参数,后面的是返回值。 if(!b){ CCLog("JniHelper::getMethodInfo error..."); }else{ CCLog("ready to invoke method..."); jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); } #endif }ok,效果如下:
各位网友,请记住这货:http://www.cnblogs.com/zisou/p/cocos2dxJQ.html 相关图片资源,源码下载地址:http://pan.baidu.com/share/link?shareid=1525180823&uk=4097703620&third=15
相关文章推荐
- 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】
- 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】
- Android实现动态圆环的图片头像控件
- android 自定义ImageView控件实现圆形图片-适用于用户头像
- cocos2d-x与安卓混编实现“更换头像”
- react native结合Android原生实现调用相机或图库选择图片设置头像
- 学习笔记之——Android中的Picasso实现圆形头像、圆角图片工具类
- Android实现本地上传图片并设置为圆形头像
- Android实现类似QQ头像点击打开相册或者拍照,并获取裁剪后的图片
- Android利用glide加载圆形图片,头像的实现
- Android实现类似换QQ头像功能(图片裁剪)
- Android实现类似换QQ头像功能(图片裁剪)
- android圆形图片,圆形头像实现方法(可直接运用到工程中)
- cocos2d-x与Android混编实现游戏支付功能
- Android实战简易教程-第二十八枪(基于Bmob实现头像图片设置和网络上传功能!)
- Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)
- Android实现本地上传图片并设置为圆形头像
- Android 自定义圆形头像CircleImageView支持加载网络图片的实现代码
- Android之圆形头像(实现相机拍摄+相册选择+图片裁剪功能)
- Cocos2dx-Android混编实现头像切换(JNI使用)