cocos2dx cpp与oc混编打开ios摄像头或图库取图

摘要:
为了完成这一要求,花了几天时间寻求帮助。这对我这个初学者来说真的很难。我希望你少走弯路。也许我没有想过内存泄漏,因为我还没有看到任何关于它的信息。我只需要先满足需求。由于新的cocos2dx项目OpenCamera需要使用Cpp和OC混合编辑,因此我们将创建一个基于Cpp的混合编辑类。也就是说,首先创建一个C++类,然后将后缀更改为mm。主要的编码样式是C++。在ios文件夹下创建一个新的C++类UtilBridge以添加Uti

为了完成这个需求,花了几天时间,各种求助。对于我这个菜鸟初学者而言确实有些难度。

在此整理一下,希望大家少走弯路。可能没考虑内存泄露等方面,因为我还没看这方面的东西,只满足需求先。

新建一个cocos2dx项目OpenCamera

由于要使用Cpp和OC混编,我们基于Cpp建一个混编类。

即先建一个C++类,再改后缀名到mm,主编码风格使用C++的。

在ios文件夹下新建C++类UtilBridge

将UtilBridge.cpp改名为UtilBridge.mm,在文件中随便打个空格保存一下。

声明静态方法后,各文件如下:

.h

 1 //
 2 //  UtilBridge.h
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #ifndef __OpenCamera__UtilBridge__
10 #define __OpenCamera__UtilBridge__
11 
12 #include "cocos2d.h"
13 using namespace cocos2d;
14 class UtilBridge:public CCObject{
15 public:
16     static void openCamera();
17 };
18 
19 #endif /* defined(__OpenCamera__UtilBridge__) */

.mm

 1 //
 2 //  UtilBridge.cpp
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #include "UtilBridge.h"
10 
11 void UtilBridge::openCamera(){
12     
13 }

打开ios摄像头等要用到oc代码,大家可以去搜一下原理。这里要用到一个代理类,我没有改RootViewController,而是新写了一个OC类,这么干我不知道会不会有问题,如果有请大家指出。

新建OC类PickerDelegate继承NSObject,文件创建好之后在声明中加上所需接口,之后文件内容如下:

.h

 1 //
 2 //  PickerDelegate.h
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface PickerDelegate : NSObject<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
12 
13 @end

.m

 1 //
 2 //  PickerDelegate.m
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #import "PickerDelegate.h"
10 
11 @implementation PickerDelegate
12 
13 
14 -(id) init
15 {
16     if(self = [super init])
17     {
18     }
19     return self;
20 }
21 
22 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
23 {
24     //CCLog("selected");
25     //处理数据
26     UIImage* image = [info valueForKey:UIImagePickerControllerOriginalImage];
27     
28     [picker dismissModalViewControllerAnimated: YES];
29     [picker release];
30 }
31 
32 
33 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
34 {
35     //CCLog("cancle");
36     [picker dismissModalViewControllerAnimated: YES];
37     [picker release];
38 }
39 
40 @end

回到UtilBridge.mm实现openCamera方法

注意:在mm中#include "PickerDelegate.h",不要写道.h文件中。

#include "PickerDelegate.h"

void UtilBridge::openCamera(){
    
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    //设置图像来源类型(先判断系统中哪种图像源是可用的)
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        picker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }else if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
        picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    }else {
        picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
    }
    
    PickerDelegate* delegate = [[PickerDelegate alloc] init];
    picker.delegate = delegate;
    [[UIApplication sharedApplication].keyWindow.rootViewController presentModalViewController:picker animated:YES];
    
}

在HelloWorld::init方法中调用openCamera

bool HelloWorld::init()
{
    if ( !CCLayer::init() )
    {
        return false;
    }
    UtilBridge::openCamera();
    return true;
}

运行一下,报错了...

貌似跟横竖屏有关,把项目调整到竖屏,再试试。我的需求就是竖屏,所以深层次的原因我就不找啦~~~

模拟器没有摄像头设备,所以打开的是图库,试摄像头要到真机上。

我们在PickerDelegate中能够拿到UIImage,拿到后转变成cocos2dx可用的格式,回调HelloWord的方法再干一些事,比如显示出来。

关于把方法当参数传进来之类的我一概不懂,所以在PickerDelegate中直接调HelloWorld,所以.m改成.mm以实现混编。

我们先说UIImage的数据转换

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    //CCLog("selected");
    //处理数据
    UIImage* image = [info valueForKey:UIImagePickerControllerOriginalImage];
    
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CCLog("%i,%i",width,height);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char* rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);
    cocos2d::CCTexture2D *pickedImage = new cocos2d::CCTexture2D();
    pickedImage->initWithData(rawData, cocos2d::kCCTexture2DPixelFormat_RGBA8888, width, height, cocos2d::CCSizeMake(width, height));
    CCLOG("%f,%f",pickedImage->getContentSize().width,pickedImage->getContentSize().height);
    
    [picker dismissModalViewControllerAnimated: YES];
    [picker release];
}

以上,我们已经把图片数据转换到了CCTexture2D,至于为何这么转,我也是搜来哒~注意引入响应头文件,这个以后就不说了。

HelloWorld声明和定义接口,接收CCTexture2D并干一些我们想干的事。

.h

void pickedPhoto(CCTexture2D* texture);

.cpp

void HelloWorld::pickedPhoto(CCTexture2D* texture){
    CCSprite* sprite = CCSprite::createWithTexture(texture);
    this->addChild(sprite);
}

OK,试一下。报错啦

断点停在了this->addChild(sprite);这一行。根据java的经验,this指针怎么可能是bad access...如果他是空指针,

delegate里的layer->pickedPhoto(pickedImage);就报啦。当然这不是java,比较纠结。

这里费死了劲,因为不会C++嘛,最后试来试去,HelloWorld的layer忘了设置tag。

CCScene* HelloWorld::scene()
{
    CCScene *scene = CCScene::create();
    HelloWorld *layer = HelloWorld::create();
    layer->setTag(1);
    scene->addChild(layer);

    return scene;
}

试一下是OK了,但是摄像头拍照的图为啥是横着的呢?

再次搜来搜去,解决之~

新建OC category扩展UIImage

cocos2dx cpp与oc混编打开ios摄像头或图库取图第1张

cocos2dx cpp与oc混编打开ios摄像头或图库取图第2张

UIImage+fixOrientation.h文件

 1 //
 2 //  UIImage+fixOrientation.h
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface UIImage (fixOrientation)
12 -(UIImage*) fixOrientation;
13 @end

UIImage+fixOrientation.m文件

 1 //
 2 //  UIImage+fixOrientation.m
 3 //  OpenCamera
 4 //
 5 //  Created by HanHongmin on 13-12-30.
 6 //
 7 //
 8 
 9 #import "UIImage+fixOrientation.h"
10 
11 @implementation UIImage (fixOrientation)
12 - (UIImage *)fixOrientation {
13     if (self.imageOrientation == UIImageOrientationUp) return self;
14     
15     UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
16     [self drawInRect:(CGRect){0, 0, self.size}];
17     UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
18     UIGraphicsEndImageContext();
19     return normalizedImage;
20 }
21 @end

以上有啥不明白的,自己搜去吧我也说不明白。这个东西用了之后,据说手机内存会突然增大大概40-50M,求良药啊

在PickerDelegate中引用上面的头文件,得到UIImage后调一下。

UIImage* image = [info valueForKey:UIImagePickerControllerOriginalImage];

  image = [image fixOrientation];

试试~~

图片拾取后发现只显示了一部分,我在控制台看到摄像头拍完后图片是2448x3264的,所以这里应该没啥问题。

自行处理一下吧。我在项目中用的时候,sprite是早就创建好的,大小是整个屏幕,只是获得Texture的时候更换到了sprite中,没啥问题的。

至于如何调节分辨率啥的,有空再研究吧。

免责声明:文章转载自《cocos2dx cpp与oc混编打开ios摄像头或图库取图》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PCB走线载流能力-揭秘一ant design pro项目配置路由菜单下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

iOS 中的 HotFix 方案总结详解

相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结。iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Apple) React Native(Facebook) JSPatch(Tencent) WaxPatch WaxPatch是一个通过Lua语言编写的iO...

IOS ——OC——NSMutableString的用法大全(个人总结)

"NSString *"这个数据类型代表一个NSString对象的指针,不是NSString对象本身。 "NSMutableString *"这个数据类型则是代表"NSMutableString"对象本身,这两者是有区别的。   这也是有的时候我们使用NSMutableString类型字符串时,要使用copy的原因,因为可能不想改变新的字符串时影...

OC基础 文件管理

OC基础  文件管理 1.文件管理类NSFileManager对象的创建:   NSFileManager *fm = [NSFileManager defaultManager]; 2.文件操作: (1)遍历查看目录下的文件:   a.遍历查看目录下的文件:contentsOfDirectorAtPath:(NSString *)path error:(...

iOS开发——OC篇&amp;amp;常用问题解答(一)

常用问题解答 1、设置 ImagePicker 的大小 ImagePicker 在 Popover Controller 总是以默认大小显示,设置 popoverContentSize 属性似乎无用。解决办法是将ImagePicker “包含”到一个定制的 ViewController 中,然后再 presentPopover 这个 ViewControl...

OC项目加入swift第三方库遇到的坑

https://www.jianshu.com/p/96d868dcd69c 2017.07.07 16:23* 字数 295 阅读 5218评论 2喜欢 4 首先,在OC项目的Podfile文件中添加如下 use_frameworks! pod 'PromiseKit', '~> 4.2.2' #任意一个swift库 然后pod install 接...

OC 学习第一天

1. OC简介 OC是一种面向对象的计算机语言。 OC实在C语言的基础上增加了一层最小的面向对象语法,完全兼容C语言。 2. OC学习目标 - 语法学习 - 建立面向对象思维能力 -建立基本项目需求分析能力 3. 面向对象思想 面向对象是一种对现实世界理解和抽象的方法,关注的是解决问题需要哪些对象,将功能封装进对象,强调具备了功能的对象。 4. 类与对象...