Cocos2d-x 3.x 选择并编辑头像功能(Android、IOS双平台实现)

大连游戏行业不是太发达,最后选择在一家应用外包公司工作,在工作和业余学习过程中积累了一点微不住道的经验,希望分享给热爱游戏的小伙伴们。

在应用开发过程中会常常有用户上传头像的功能,在网上找了N多资料发现没有人具体介绍过该用cocos2d-x实现。这篇文章就来介绍一下如何在Android和IOS平台上实现该功能。

欢迎热爱游戏开发的小伙伴骚扰:

电邮:[email protected]

企鹅:601322806

先传一张完成后的图片一饱眼福

直接上代码:

头文件 ImagePicker.h

/**************************************************************************
 * Copyright (c) 2015, pxbomb, All rights reserved.

 * File		: ImagePicker.h
 * Date		: 2015/06/02 18:02
 * Author	: 田伟汉
 * Email	: [email protected]
 * Depict	: 图像选择器
 **************************************************************************/
#ifndef _IMAGEPICKER_H_
#define _IMAGEPICKER_H_

#include "cocos2d.h"

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"
#include <jni.h>
#endif	// CC_PLATFORM_ANDROID

/**
 * 图像选择器
 */
class ImagePicker
{
public:
    // 获取选择器单例
    static ImagePicker* getInstance();

    // 销毁
    static void destoryInstance();
public:
    // 显示本地相册与相机选择器
    void callImagePickerWithPhotoAndCamera(const std::function<void(std::string)>& callback);

    // 设置监听
    void setListener(const std::function<void(std::string)>& callback);

    // 移除监听
    void removeListener();

    // 打开相册
    void openPhoto();

    // 打开相机
    void openCamera();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    // 设置AppController
    void setViewController(void* viewController);
#endif // CC_PLATFORM_IOS

protected:
    // 初始化
    bool init();

    ImagePicker();

protected:
    std::function<void(std::string)> m_callback;
    static ImagePicker* s_instance;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    void* m_viewController;
#endif // CC_PLATFORM_IOS

};

#endif // _IMAGEPICKER_H_

实现文件 ImagePicker.cpp

#include "ImagePicker.h"
//--------------------------------------------------
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#import  "ImagePickerViewController.h"
#import  "RootViewController.h"
#endif
//--------------------------------------------------
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#define JAVA_CLASS              "org/cocos2dx/cpp/ImagePicker"
#define JAVA_FUNC_OPEN_PHOTO    "openPhoto"
#define JAVA_FUNC_OPEN_CAMERA   "openCamera"
#endif
//--------------------------------------------------
USING_NS_CC;
//--------------------------------------------------
ImagePicker* ImagePicker::s_instance = NULL;
//--------------------------------------------------
ImagePicker* ImagePicker::getInstance()
{
    if (s_instance == NULL)
    {
        s_instance = new ImagePicker();
    }
    return s_instance;
}
//--------------------------------------------------
void ImagePicker::destoryInstance()
{
    CC_SAFE_DELETE(s_instance);
}
//--------------------------------------------------
ImagePicker::ImagePicker()
:m_callback(nullptr)
{
    Director::getInstance()->getEventDispatcher()->addCustomEventListener("ImagePickerEvent", [=](EventCustom* eve)
    {
        std::string* path = (std::string*)eve->getUserData();
        if (path && m_callback != nullptr)
        {
            m_callback(*path);
        }
    });
}
//--------------------------------------------------
void ImagePicker::callImagePickerWithPhotoAndCamera(const std::function<void(std::string)>& callback)
{
    s_instance->init();
    setListener(callback);
}
//--------------------------------------------------
void ImagePicker::setListener(const std::function<void(std::string)>& callback)
{
    m_callback = callback;
}
//--------------------------------------------------
void ImagePicker::removeListener()
{
    m_callback = nullptr;
}
//--------------------------------------------------
void ImagePicker::openPhoto()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    ImagePickerViewController* imagePickerViewController = [[ImagePickerViewController alloc] initWithNibName:nil bundle:nil];

    RootViewController* _viewController = (RootViewController*)m_viewController;
    [_viewController.view addSubview:imagePickerViewController.view];

    [imagePickerViewController localPhoto];
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo info;
    bool ret = JniHelper::getStaticMethodInfo(info, JAVA_CLASS, JAVA_FUNC_OPEN_PHOTO,"()V");
    if (ret)
    {
        info.env->CallStaticVoidMethod(info.classID, info.methodID);
    }
#endif
}
//--------------------------------------------------
void ImagePicker::openCamera()
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    ImagePickerViewController* imagePickerViewController = [[ImagePickerViewController alloc] initWithNibName:nil bundle:nil];

    RootViewController* _viewController = (RootViewController*)m_viewController;
    [_viewController.view addSubview:imagePickerViewController.view];

    [imagePickerViewController takePhoto];
#endif

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo info;
    bool ret = JniHelper::getStaticMethodInfo(info, JAVA_CLASS, JAVA_FUNC_OPEN_CAMERA,"()V");
    if (ret)
    {
        info.env->CallStaticVoidMethod(info.classID, info.methodID);
    }
#endif
}
//--------------------------------------------------
bool ImagePicker::init()
{
    cocos2d::Size visibleSize = Director::getInstance()->getVisibleSize();

    //-------------------------------------
    // 根层
    //-------------------------------------
    LayerColor* m_layer = LayerColor::create(Color4B(0, 0, 0, 125));
    m_layer->retain();
    //-------------------------------------
    // 按钮背景
    //-------------------------------------
    Sprite* sprite = Sprite::create("ImagePicker/bk.png");
    sprite->setAnchorPoint(Vec2(0.5, 0));
    sprite->setPosition(Vec2(visibleSize.width/2, 0));
    m_layer->addChild(sprite);
    //-------------------------------------
    // 按钮
    //-------------------------------------
    Menu* menu = Menu::create();
    menu->setPosition(Vec2::ZERO);
    m_layer->addChild(menu);
    //-------------------------------------
    MenuItemImage* btnPhoto  = MenuItemImage::create("ImagePicker/ButtonPhoto.png",  "ImagePicker/ButtonPhoto1.png",  [=](Ref* p)
    {
        openPhoto();
    });
    btnPhoto->setAnchorPoint(Vec2(0.5, 1));
    btnPhoto->setPosition(Vec2(visibleSize.width / 2, 280));
    menu->addChild(btnPhoto);
    //-------------------------------------
    MenuItemImage* btnCamera = MenuItemImage::create("ImagePicker/ButtonCamera.png", "ImagePicker/ButtonCamera1.png", [=](Ref* p)
    {
        openCamera();
    });
    btnCamera->setAnchorPoint(Vec2(0.5, 1));
    btnCamera->setPosition(btnPhoto->getPosition() + Vec2(0, -btnPhoto->getContentSize().height));
    menu->addChild(btnCamera);
    //-------------------------------------
    MenuItemImage* btnCancel = MenuItemImage::create("ImagePicker/ButtonCancel.png", "ImagePicker/ButtonCancel1.png", [=](Ref* p)
    {
        float height = sprite->getContentSize().height;

        MoveBy* move = MoveBy::create(0.2, Vec2(0, -height));
        sprite->runAction(move);
        menu  ->runAction(move->clone());

        Sequence* seq = Sequence::createWithTwoActions(FadeOut::create(0.2), RemoveSelf::create());
        m_layer->runAction(seq);
    });
    btnCancel->setAnchorPoint(Vec2(0.5, 1));
    btnCancel->setPosition(btnCamera->getPosition() + Vec2(0, -btnCamera->getContentSize().height - 20));
    menu->addChild(btnCancel);
    //-------------------------------------
    // 文字
    //-------------------------------------
    Label* textPhoto  = Label::createWithSystemFont("Photo",  "", 24);
    textPhoto->setPosition(btnPhoto->getContentSize() / 2);
    textPhoto->setTextColor(Color4B::BLACK);
    btnPhoto->addChild(textPhoto);
    //-------------------------------------
    Label* textCamera = Label::createWithSystemFont("Camera", "", 24);
    textCamera->setPosition(btnPhoto->getContentSize() / 2);
    textCamera->setTextColor(Color4B::BLACK);
    btnCamera->addChild(textCamera);
    //-------------------------------------
    Label* textCancel = Label::createWithSystemFont("Cancel", "", 24);
    textCancel->setPosition(btnPhoto->getContentSize() / 2);
    textCancel->setTextColor(Color4B::BLACK);
    btnCancel->addChild(textCancel);
    //-------------------------------------
    // 准备显示
    //-------------------------------------
    Director::getInstance()->getRunningScene()->scheduleOnce([=](float time)
    {
        Director::getInstance()->getRunningScene()->addChild(m_layer, INT_MAX);
        m_layer->release();

        float height = sprite->getContentSize().height;

        sprite->setPositionY(sprite->getPositionY() - height);
        menu  ->setPositionY(menu->getPositionY()   - height);

        MoveBy* move = MoveBy::create(0.3, Vec2(0, height));
        sprite->runAction(move);
        menu  ->runAction(move->clone());

        m_layer->setOpacity(0);
        m_layer->runAction(FadeTo::create(0.2, 125));

    }, 0.1, "ImagePickerScheduleOnce");
    //-------------------------------------
    // 截断事件
    //-------------------------------------
    EventListenerTouchOneByOne* touchEvent = EventListenerTouchOneByOne::create();
    touchEvent->setSwallowTouches(true);
    touchEvent->onTouchBegan = [=](Touch* touch, Event* eve)
    {
        if(sprite->getBoundingBox().containsPoint(touch->getLocation()))
            return true;

        float height = sprite->getContentSize().height;

        MoveBy* move = MoveBy::create(0.2, Vec2(0, -height));
        sprite->runAction(move);
        menu  ->runAction(move->clone());

        Sequence* seq = Sequence::createWithTwoActions(FadeOut::create(0.2), RemoveSelf::create());
        m_layer->runAction(seq);

        return true;
    };
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchEvent, sprite);
    //-------------------------------------
    return true;
}
//--------------------------------------------------
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
void  ImagePicker::setViewController(void* viewController)
{
    m_viewController = viewController;
}
#endif
//--------------------------------------------------
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
extern "C"
{
    void Java_org_cocos2dx_cpp_ImagePicker_onImageSaved(JNIEnv* env, jobject thiz, jstring path)
    {
        std::string strPath = JniHelper::jstring2string(path);
        Director::getInstance()->getEventDispatcher()->dispatchCustomEvent("ImagePickerEvent", &strPath);
    }
}
#endif
//--------------------------------------------------

为工程添加资源:

(图片资源和代码下载地址:点击打开链接)

分平台实现:

------------------------------------------

Android

------------------------------------------

1. 打开Eclipse在org.cocos2x.cpp(加入你没改过的话)包名下新建“ImagePicker.java”文件

ImagePicker.java具体代码如下:

public class ImagePicker{

<span style="white-space:pre">	</span>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/*";

    private static ImagePicker instance = null;
    private static Activity    activity = null;

    public static native void onImageSaved(String path);

    public static ImagePicker getInstance(){
    	if(instance == null){
    		instance = new ImagePicker();
    	}
    	return instance;
    }

    // 初始化
    public void init(Activity activity){
    	ImagePicker.activity = activity;
    }

    // 打开相册
	static public void openPhoto(){
		Intent intent = new Intent(Intent.ACTION_PICK, null);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
        activity.startActivityForResult(intent, PHOTOZOOM);
	}

	// 打开相机
	static public void openCamera(){
    	Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(activity.getFilesDir(), "@cc_cameraCache.jpg")));
        activity.startActivityForResult(intent, PHOTOHRAPH);
    }

	// 回调
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if (resultCode == NONE)
            return;

        // 拍照
        if (requestCode == PHOTOHRAPH) {
            File picture = new File(activity.getFilesDir() + "/@cc_cameraCache.jpg");
            startPhotoZoom(Uri.fromFile(picture));
        }

        if (data == null)
            return;

        // 读取相册缩放图片
        if (requestCode == PHOTOZOOM) {
            startPhotoZoom(data.getData());
        }

        // 处理结果
        if (requestCode == PHOTORESOULT) {
            Bundle extras = data.getExtras();
            if (extras != null) {
                Bitmap photo = extras.getParcelable("data");
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);

                // XXX/@ci_8888-8888-8888-8888.jpg
                String path = activity.getFilesDir() + "/@ci_" + UUID.randomUUID().toString() + ".jpg";
                saveMyBitmap(path, photo);

                // 通知C++层已保存图片 并返回路径
                onImageSaved(path);
            }
        }
	}

	public void startPhotoZoom(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, IMAGE_UNSPECIFIED);
        intent.putExtra("crop", "true");
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        intent.putExtra("outputX", 100);
        intent.putExtra("outputY", 100);
        intent.putExtra("return-data", true);
        activity.startActivityForResult(intent, PHOTORESOULT);
    }

	public void saveMyBitmap(String filePath, Bitmap mBitmap){
    	File f = new File(filePath);
    	try {
    		f.createNewFile();
    	} catch (IOException e) {
    	}
    	FileOutputStream fOut = null;
    	try {
    		fOut = new FileOutputStream(f);
    	} catch (FileNotFoundException e) {
    		e.printStackTrace();
    	}
    	mBitmap.compress(Bitmap.CompressFormat.JPEG, 70, fOut);
    	try {
    		fOut.flush();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    	try {
    		fOut.close();
    	} catch (IOException e) {
    		e.printStackTrace();
    	}
    }
}

2. 在Android入口进行初始化

打开AppActivity.java文件,复写OnCreate()与onActivityResult()方法。

在OnCreate方法中对我们的类初始化:“ImagePicker.getInstance().init(this);”

在onActivityResult()中将回调参数传递到ImagePicker中:“ImagePicker.getInstance().onActivityResult(requestCode, resultCode, data);”

AppActivity.java具体代码:

public class AppActivity extends Cocos2dxActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		ImagePicker.getInstance().init(this);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);

		ImagePicker.getInstance().onActivityResult(requestCode, resultCode, data);
	}
}

3. 最后在AndroidManifest.xml加入访问相机权限"<uses-permission android:name="android.permission.CAMERA"/>"

------------------------------------------

 IOS

------------------------------------------

1. 将开始创建的ImagePicker.cpp文件后缀名改为.mm文件。

2. 在proj.ioc_mac/ios文件夹下创建两个文件,分别为ImagePickerViewController.h、ImagePickerViewController.mm

ImagePickerViewController.h具体代码:

#import <UIKit/UIKit.h>

@interface ImagePickerViewController : UIViewController<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
    NSString* filePath;
}

// 打开本地相册
- (void)localPhoto;

// 打开相机
- (void)takePhoto;

@end

ImagePickerViewController.mm具体代码

#import "ImagePickerViewController.h"
#import "cocos2d.h"

@interface ImagePickerViewController ()

@end

@implementation ImagePickerViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //[self localPhoto];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)localPhoto{
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.delegate      = self;
    picker.sourceType    = UIImagePickerControllerSourceTypePhotoLibrary;
    picker.allowsEditing = YES;
    //[self presentModalViewController:picker animated:YES];
    [self presentViewController:picker animated:YES completion:^(void){
        NSLog(@"Imageviewcontroller is presented");
    }];
    [picker release];

    NSLog(@"-(void)localPhoto();");
}

- (void)takePhoto{
    UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        UIImagePickerController* picker = [[UIImagePickerController alloc] init];
        picker.delegate = self;
        //设置拍照后的图像可编辑
        picker.allowsEditing = YES;
        picker.sourceType = sourceType;
        [picker release];
        [self presentModalViewController:picker animated:YES];
    }
    else{
        NSLog(@"模拟器中无法打开照相机,请在真机中调试");
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    NSString *type = [info objectForKey:UIImagePickerControllerMediaType];

    //当选择的类型是图片
    if ([type isEqualToString:@"public.image"])
    {
        //先把图片转成NSData
//        UIImage* image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        UIImage* image = [info objectForKey:@"UIImagePickerControllerEditedImage"];
        NSData *data;
        if (UIImagePNGRepresentation(image) == nil)
        {
            data = UIImageJPEGRepresentation(image, 1.0);
        }
        else
        {
            data = UIImagePNGRepresentation(image);
        }

        //图片保存的路径
        //这里将图片放在沙盒的documents文件夹中
        NSString * DocumentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];

        //文件管理器
        NSFileManager *fileManager = [NSFileManager defaultManager];

        //生成唯一字符串
        NSString* uuid = [[NSUUID UUID] UUIDString];

        //文件名
        NSString* fileName = [NSString stringWithFormat:@"/%@.png", uuid];

        //把刚刚图片转换的data对象拷贝至沙盒中 并保存为XXXXXXXX-XXXX-XXXX....XXXX.png
        [fileManager createDirectoryAtPath:DocumentsPath withIntermediateDirectories:YES attributes:nil error:nil];
        [fileManager createFileAtPath:[DocumentsPath stringByAppendingString:fileName] contents:data attributes:nil];

        //得到选择后沙盒中图片的完整路径
        filePath = [[NSString alloc]initWithFormat:@"%@%@", DocumentsPath, fileName];

        //关闭相册界面
        [picker dismissModalViewControllerAnimated:YES];

        std::string strFilePath = [filePath UTF8String];
        cocos2d::Director::getInstance()->getEventDispatcher()->dispatchCustomEvent("ImagePickerEvent", &strFilePath);
    }

}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    NSLog(@"您取消了选择图片");
    [picker dismissModalViewControllerAnimated:YES];
}

@end

3. 修改原工程AppController.mm文件,加入一行“ImagePicker::getInstance()->setViewController(_viewController);”用来初始化。

AppController.mm具体代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    cocos2d::Application *app = cocos2d::Application::getInstance();
    app->initGLContextAttrs();
    cocos2d::GLViewImpl::convertAttrs();

    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];

    // Init the CCEAGLView
    CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds]
                                         pixelFormat: (NSString*)cocos2d::GLViewImpl::_pixelFormat
                                         depthFormat: cocos2d::GLViewImpl::_depthFormat
                                  preserveBackbuffer: NO
                                          sharegroup: nil
                                       multiSampling: NO
                                     numberOfSamples: 0 ];

    // Use RootViewController manage CCEAGLView
    _viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    _viewController.wantsFullScreenLayout = YES;
    _viewController.view = eaglView;

    //----------------------------------
    // 初始化ImagePicker
    //----------------------------------
    ImagePicker::getInstance()->setViewController(_viewController);
    //----------------------------------

    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // warning: addSubView doesn't work on iOS6
        [window addSubview: _viewController.view];
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:_viewController];
    }

    [window makeKeyAndVisible];

    [[UIApplication sharedApplication] setStatusBarHidden:true];

    // IMPORTANT: Setting the GLView should be done after creating the RootViewController
    cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView(eaglView);
    cocos2d::Director::getInstance()->setOpenGLView(glview);

    app->run();

    return YES;
}

OK,接下来就是在C++代码中调用了,你只需要在想使用头像选择器的时候,调用这一行代码:

ImagePicker::getInstance()->callImagePickerWithPhotoAndCamera([=](std::string path)
    {
        //做你想做的事情
    });

忘了说明,参数path就是你已经选择并编辑后,图片的真实路径。

咳咳,请各位大神轻喷,喜欢游戏的程序孩纸伤不起~不说了,回家LOL去了~

时间: 2024-10-12 01:47:32

Cocos2d-x 3.x 选择并编辑头像功能(Android、IOS双平台实现)的相关文章

Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)

大连游戏产业不是很发达,最后,选择一个应用程序外包公司.积累的工作和学习过程中的一点业余生活微信体验,我想分享的游戏小朋友的爱. 在应用开发过程中会经常实用户上传头像的功能,在网上找了N多资料发现没有人详细介绍过该用cocos2d-x实现.这篇文章就来介绍一下怎样在Android和IOS平台上实现该功能. 先传一张完毕后的图片一饱眼福:= = 怎么不好用呢~ 直接上代码: 头文件 ImagePicker.h /*******************************************

[DevExpress]设置RepositoryItemComboBox只可下拉选择不可编辑

将TextEditStyle属性设置如下即可: 希望有所帮助! [DevExpress]设置RepositoryItemComboBox只可下拉选择不可编辑

升级IOS8游戏上传自定义头像功能失效的问题

为了支持arm64,之前已经折腾了很久,昨晚打包准备提交苹果审核时,测试那边的同事反馈说游戏上传自定义头像功能不可用了. 游戏上传自定义功能的简介:卡牌游戏最初是<比武招亲>中有一个充VIP之后就可使用了上传自定义功能的特权,我们的游戏就"复制"了该功能.   具体实现就是点击游戏内换自定义头像的按钮后,调用不同平台相应的方法,获取用户选择的图片数据,然后将图片裁剪再传给后台保存至特定的目录下.   测试设备是ipad air2,系统版本IOS 8.0.1,点击游戏内的按钮

第四十一课、编辑交互功能的实现

一.编辑交互功能 1.编辑器中常规的编辑交互功能 2.QPlainTextEdit提供了丰富的交互接口 3.信号与槽的连接 编辑器代码修改:将action触发的信号映射到QPlainTextEdit对象的槽函数   二.文本编辑器中的界面状态 1.不是任何时候都可以复制.粘贴.撤销.重做(比如开始没有数据时) 2.QPlainTextEdit能够发送与界面状态相关的信号 3.实现步骤 (1).连接界面状态信号到自定义的槽函数 (2).通过文本信息找到对应的QAction对象 QAction* M

第41课 编辑交互功能的实现

1. 常规编辑交互功能 (1)复制(Copy).粘贴(Paste).剪切(Cut).撤销(Undo).重做(Redo).删除(Delete) (2)QPlainTextEdit提供了丰富的交互功能接口 2. 信号与槽的连接 [编程实验]基本编辑功能实现 3. 文本编辑器中的界面状态 (1)不是任何时候都能够进行复制.粘贴.撤销或重做.(即部分按钮得灰化处理) (2)QPlainTextEdit能够发送与界面状态相关的信号 ①void copyAvailable(bool yes); ②void

Android 跳转系统选择本地视频的功能

今天在项目开发的过程中产品要求添加选择本地视频的功能,于是就翻阅和查找各种资料,进行功能的开发,但是在开发过程中发现,各种不同的品牌的手机跳转至系统选择本地视频的功能结果不太一样,所以我就对一些主流的品牌进行了测试,现做如下总结: 1.选择本地视频的功能 Button click event: Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTEN

可在广域网部署运行的QQ高仿版 -- GG叽叽V3.5,增加自拍头像功能、细节优化(源码)

距离上次发版本(GG叽叽V3.4,增加系统设置.最近联系人.群功能)又有1个月了,在这个月内,由于空闲时间不是很多,所以,GG增加的主要功能只是拍照并设定其为自己头像.修改密码.删除好友.以及一些bug的修改.我试着列了一下接下来GG要优化的地方,总共达20多条,看来GG离一个正式的产品还有很长的路要走.慢慢来吧! 一.GG V3.5 新增功能展现 1.自拍头像 2.修改密码 3.删除好友 4.其它 (1)主窗口允许改变大小. (2)修复bug:聊天发消息时,如果截图很大,对方就收不到. (3)

MonoTouch - iOS 使用 UIImagePickerController 打开图片库和相机选择图片修改头像

Application tried to present modally an active controller <UIImagePickerController: 0x7b6ff400> 1,AddGestureRecognizer为图片视图添加事件 //圆角头像 _avatarView = new UIImageView(new RectangleF(_blockSpace, _blockSpace, 2 * _avatarRadius, 2 * _avatarRadius)); UII

Jcrop ,.net仿百度上传在线编辑头像

(源码下载链接: http://pan.baidu.com/s/1pJVxMAn 密码: gbuz)  个人习惯,代码不贴出来,自己去云盘下. 我们先看一下百度上传头像的页面.如下图. 再 看看我做的效果. 图1 图2 上面是我做出的效果,灰色是一个400X400的背景,图片会自动适应 (图1和图2 一个横向一个是纵向),宽度和高度始终能放入这个背景中. 介绍一下使用的技术,Jquery, Jcrop ,ajaxfileupload.js . 我们先看一下百度上传头像的页面.如下图. 再 看看我