cocos2d-x调用摄像头和相册并裁减图片

cocos2d-x调用摄像头和相册并裁减图片,第1张

概述最近做个小游戏需要调用手机图库和摄像头裁减图片,发现网上很多教程不是太全,有的安卓端裁减不了大图,下面是完整代码,可以裁减高清图的。 完整拼图游戏下载: https://github.com/sky068/Puzzles 1、首先是跨平台入口代码,iOS平台需要把ImageCrop.cpp改成ImageCrop.mm,并且在AppController.mm里调用setViewController

最近做个小游戏需要调用手机图库和摄像头并裁减图片,发现网上很多教程不是太全,有的安卓端裁减不了大图,下面是完整代码,可以裁减高清图的。

完整拼图游戏下载:
@L_301_0@

1、首先是跨平台入口代码,iOS平台需要把ImageCrop.cpp改成ImageCrop.mm,并且在AppController.mm里调用setVIEwController(voID* vIEwController)把rootVIEw传进来初始化m_vIEwController

#ifndef ImageCrop_hpp#define ImageCrop_hpp#include <stdio.h>#include "cocos2d.h"USING_NS_CC;#define kImageCropEvent "ImageCropEvent"class ImageCrop {public:    ImageCrop();    static ImageCroP* getInstance();    static voID destroyInstance();    voID openCamera(std::function<voID(std::string)> callback);    voID openPhoto(std::function<voID(std::string)> callback);#if ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)    //设置AppController iOS平台在AppController.mm里调用把rootVIEwController传递过来    voID setVIEwController(voID* vIEwController);    voID *m_vIEwController;#endifprivate:    static ImageCroP* _instance;    std::function<voID(std::string)> _callback;};#endif//// ImageCrop.cpp// PhotoCrop//// Created by xujw on 15/12/28.////#include "ImageCrop.hpp"#if ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)#import "ImagePickerVIEwController.h"#import "RootVIEwController.h"#endif#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)#include "platform/androID/jni/JniHelper.h"#include <jni.h>#define JAVA_CLASS "org/cocos2dx/cpp/ImageCrop"#define JAVA_FUNC_OPEN_PHOTO "openPhoto"#define JAVA_FUNC_OPEN_CAMERA "openCamera"#endifImageCrop::ImageCrop():_callback(nullptr){    Director::getInstance()->getEventdispatcher()->addCustomEventListener(kImageCropEvent,[=](EventCustom *event)    {        std::string *imgPath = (std::string*)event->getUserData();        _callback(*imgPath);    });}ImageCroP* ImageCrop::_instance = nullptr;ImageCroP* ImageCrop::getInstance(){    if (!_instance)    {        _instance = new (std::nothrow) ImageCrop();    }    return _instance;}voID ImageCrop::destroyInstance(){    CC_SAFE_DELETE(_instance);}voID ImageCrop::openCamera(std::function<voID (std::string)> callback){    _callback = callback;#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}voID ImageCrop::openPhoto(std::function<voID (std::string)> callback){    _callback = callback;#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_FUNC_OPEN_PHOTO,info.methodID);    }#endif}#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)voID ImageCrop::setVIEwController(voID *vIEwController){    m_vIEwController = vIEwController;}#endif//--------Java回调C++--------native 方法#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)extern "C"{    voID Java_org_cocos2dx_cpp_ImageCrop_onImageSaved(jnienv *env,jobject thiz,Jstring path)    {        std::string strPath = JniHelper::Jstring2string(path);        //必须这样,否则由于线程问题会显示黑块无法正常创建精灵        Director::getInstance()->getScheduler()->performFunctionInCocosThread([=,strPath]()mutable{            Director::getInstance()->getEventdispatcher()->dispatchCustomEvent(kImageCropEvent,&strPath);        });    }}#endif

2、iOS端代码,.m文件改成.mm文件

#ifndef ImagePickerVIEwController_h#define ImagePickerVIEwController_h#import <UIKit/UIKit.h>@interface ImagePickerVIEwController:UIVIEwController<UINavigationControllerDelegate,UIImagePickerControllerDelegate>{    Nsstring *filePath;}//打开本地相册-(voID)localPhoto;//打开相机-(voID)takePhoto;@end#endif#import <Foundation/Foundation.h>#import "ImagePickerVIEwController.h"@interface ImagePickerVIEwController ()@end@implementation ImagePickerVIEwController-(voID)vIEwDIDLoad{    [super vIEwDIDLoad];}-(voID)vIEwDIDUnload{    [super vIEwDIDUnload];}-(voID)dIDReceiveMemoryWarning{    [super dIDReceiveMemoryWarning];}-(voID)localPhoto{    NSLog(@"-(voID)localPhoto");    UIImagePickerController *picker = [[UIImagePickerController alloc]init];    picker.delegate = self;    picker.sourceType = UIImagePickerControllerSourceTypePhotolibrary;    picker.allowsEditing = YES;    [self presentVIEwController:picker animated:YES completion:^(voID)                                                                {                                                                    NSLog(@"ImageVIEwController is presented");                                                                }];    [picker release];}-(voID)takePhoto{    UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;    if ([UIImagePickerController isSourceTypeAvailable:sourceType])    {        UIImagePickerController *picker = [[UIImagePickerController alloc]init];        picker.delegate = self;        //设置拍照后可以编辑        picker.allowsEditing = YES;        picker.sourceType = sourceType;        [self presentVIEwController:picker animated:YES completion:^(voID)                                                                    {                                                                    NSLog(@"ImageVIEwController is presented");                                                                    }];    }    else    {        NSLog(@"模拟器无法使用相机,请在真机中调试");    }    NSLog(@"-(voID)takePhoto");}-(voID)imagePickerController:(UIImagePickerController *)picker dIDFinishPickingMediawithInfo:(NSDictionary<Nsstring *,ID> *)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/image文件夹中        Nsstring *documentsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"documents"];        Nsstring *imgPath = [documentsPath stringByAppendingPathComponent:@"image"];        //文件管理器        NSfileManager *fileManager = [NSfileManager defaultManager];        //生成唯一字符串        Nsstring *uuID = [[NSUUID UUID]UUIDString];        //生成文件名        Nsstring *filename = [Nsstring stringWithFormat:@"%@.png",uuID];        //把刚刚由图片转成的data对象拷贝至沙盒中 并保存为xxxxx-xxxx-xxx...xxx.png        /******保存之前最好先清空下,不然占用磁盘越来越大********/        [fileManager removeItemAtPath:imgPath error:nil];        /*************************************************/        [fileManager createDirectoryAtPath:imgPath withIntermediateDirectorIEs:YES attributes:nil error:nil];        [fileManager createfileAtPath:[imgPath stringByAppendingPathComponent:filename] contents:data attributes:nil];        //得到选择后沙盒中图片的完整路径        filePath = [[Nsstring alloc]initWithFormat:@"%@",[imgPath stringByAppendingPathComponent:filename]];        //关闭相册界面        [picker dismissVIEwControllerAnimated:YES completion:^(voID){}];        //通知ImageCrop完成取图        std::string strfilePath = [filePath UTF8String];        cocos2d::Director::getInstance()->getEventdispatcher()->dispatchCustomEvent("ImageCropEvent",&strfilePath);    }}-(voID)imagePickerControllerDIDCancel:(UIImagePickerController *)picker{    NSLog(@"您取消了照片选择");    [picker dismissVIEwControllerAnimated:YES completion:^(voID){}];}@end

3、安卓端,安卓平台需要把ImageCrop.java导入工程包里(src下org.cocos2dx.cpp包里),在主activity(AppActivity.java)的onCreate里调用ImageCrop.getInstance().initimageCrop(this)初始化,然后重载onActivityResult并回调ImageCrop的onActivityResult方法

ImageCrop.java:

package org.cocos2dx.cpp;import java.io.file;import java.io.fileNotFoundException;import androID.app.Activity;import androID.content.Intent;import androID.graphics.Bitmap;import androID.graphics.BitmapFactory;import androID.net.Uri;import androID.os.Environment;import androID.provIDer.MediaStore;import androID.util.Log;public class ImageCrop {    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 ImageCrop instance = null;    private static Activity activity = null;    private static String TAG = "ImageCrop";    public static native voID onImageSaved(String path);    //拍摄照片保存路径    private static String savePath = Environment.getExternalStorageDirectory() +"/CropImage";    private static String photoname = "";    private static Uri imguri = null;    public static ImageCrop getInstance()    {        if(null == instance)        {            instance = new ImageCrop();        }        return instance;    }    //初始化    public voID init(Activity activity)    {        ImageCrop.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()    {        file destDir = new file(savePath);        if (!destDir.exists())         {            destDir.mkdirs();        }        photoname = "temp.jpg";        file file = new file(savePath + "/" + photoname);        imguri = Uri.fromfile(file);        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        intent.putExtra(MediaStore.EXTRA_OUTPUT,imguri);        activity.startActivityForResult(intent,PHOTOHRAPH);    }    //回调    public voID onActivityResult(int requestCode,int resultCode,Intent data)    {        if (resultCode == NONE)            return;        // 拍照 不能使用data,因为没有返回是空的        if (requestCode == PHOTOHRAPH)        {            if (imguri == null)            {                Log.e(TAG,"PHOTOHRAPH imguri is null");                return;            }            startPhotoZoom(imguri);        }        if (requestCode == PHOTOZOOM)        {             // 读取相册缩放图片            if (data==null )            {                Log.e(TAG,"data is null");                return;            }            if (data.getData()==null)             {                Log.e(TAG,"data.getData() is null");                return;            }            startPhotoZoom(data.getData());        }        // 处理结果        if (requestCode == PHOTORESOulT)        {            Bitmap bitmap = decodeUriAsBitmap(imguri);            if (bitmap == null)            {                Log.e(TAG,"bitmap is null");            }            Log.e("ImageCrop","图片已经保存,通知c++层,");            onImageSaved(savePath + "/" + photoname);        }    }    public voID startPhotoZoom(Uri uri)    {        photoname = System.currentTimeMillis() + ".jpg";        file file = new file(savePath,photoname);        imguri = Uri.fromfile(file);        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",600);        intent.putExtra("outputY",600);        intent.putExtra("return-data",false);        intent.putExtra(MediaStore.EXTRA_OUTPUT,imguri);        activity.startActivityForResult(intent,PHOTORESOulT);    }    private Bitmap decodeUriAsBitmap(Uri uri)    {        Bitmap bitmap = null;        try {            bitmap = BitmapFactory.decodeStream(activity.getContentResolver().openinputStream(uri));        } catch (fileNotFoundException e) {            // Todo: handle exception            e.printstacktrace();            return null;        }        return bitmap;    }}

4、示例
HelloWorld工程里直接引入ImageCrop.hpp,调用拍照或者打开相册即可,裁减完成后会返回图片保存路径,直接就可以在C++环境里创建精灵等 *** 作了,欧了!

#include "HelloWorldScene.h"#include "ImageCrop.hpp"USING_NS_CC;Scene* HelloWorld::createScene(){    // 'scene' is an autorelease object    auto scene = Scene::create();    // 'layer' is an autorelease object    auto layer = HelloWorld::create();    // add layer as a child to scene    scene->addChild(layer);    // return the scene    return scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }    Size visibleSize = Director::getInstance()->getVisibleSize();    Vec2 origin = Director::getInstance()->getVisibleOrigin();    /////////////////////////////    // 2. add a menu item with "X" image,which is clicked to quit the program    // you may modify it.    // add a "close" icon to exit the progress. it's an autorelease object    auto closeItem = MenuItemImage::create(                                           "Closenormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback,this));    closeItem->setposition(Vec2(origin.x + visibleSize.wIDth - closeItem->getContentSize().wIDth/2,origin.y + closeItem->getContentSize().height/2));    auto openPhoto = MenuItemFont::create("打开相册",[=](Ref*)    {        ImageCrop::getInstance()->openPhoto([=](std::string path)        {            cclOG("photo path:%s",path.c_str());            _img -> removeFromParent();            _img = Sprite::create(path);            this->addChild(_img);            _img->setposition(Vec2(visibleSize.wIDth/2 + origin.x,visibleSize.height/2 + origin.y));        });    });    openPhoto->setposition(Vec2(origin.x + openPhoto->getContentSize().wIDth/2,origin.y + openPhoto->getContentSize().height/2));    auto openCamera = MenuItemFont::create("打开相机",[=](Ref*)                                          {                                              ImageCrop::getInstance()->openCamera([=](std::string path)                                                                                  {                                                                                      cclOG("photo path:%s",path.c_str());                                                                                      _img -> removeFromParent();                                                                                      _img = Sprite::create(path);                                                                                      this->addChild(_img);                                                                                      _img->setposition(Vec2(visibleSize.wIDth/2 + origin.x,visibleSize.height/2 + origin.y));                                                                                  });                                          });    openCamera->setposition(Vec2(origin.x + openCamera->getContentSize().wIDth/2,origin.y + openCamera->getContentSize().height));    auto menu = Menu::create(closeItem,openPhoto,openCamera,NulL);    menu->setposition(Vec2::ZERO);    this->addChild(menu,1);    /////////////////////////////    // 3. add your codes below...    // add a label shows "Hello World"    // create and initialize a label    auto label = Label::createWithTTF("Hello World","Fonts/Marker Felt.ttf",24);    // position the label on the center of the screen    label->setposition(Vec2(origin.x + visibleSize.wIDth/2,origin.y + visibleSize.height - label->getContentSize().height));    // add the label as a child to this layer    this->addChild(label,1);    // add "HelloWorld" splash screen"    _img = Sprite::create("HelloWorld.png");    // position the sprite on the center of the screen    _img->setposition(Vec2(visibleSize.wIDth/2 + origin.x,visibleSize.height/2 + origin.y));    // add the sprite as a child to this layer    this->addChild(_img,0);    return true;}voID HelloWorld::menuCloseCallback(Ref* pSender){    Director::getInstance()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)    exit(0);#endif}

本文参考:
http://www.jb51.cc/article/p-fgjeqgzd-bbz.html

http://www.myexception.cn/operating-system/1937511.html

总结

以上是内存溢出为你收集整理的cocos2d-x调用摄像头和相册并裁减图片全部内容,希望文章能够帮你解决cocos2d-x调用摄像头和相册并裁减图片所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1076235.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存