Cocos2d-x에서 OpenCV를 사용하고 싶었지만 ...
전회에 이어 cocos2d-x를 만지고 있었습니다만, 동영상 재생용의 노드가 cocos2d-x가 아닌 것 같네요.
그래서 저의 특기 분야인 OpenCV를 사용하여 동영상 파일에서 Sprite의 리스트를 작성해 애니메이션 시키려고 생각해 구현해 보았습니다.
VideoNode.h
#import <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <2d/CCAnimation.h>
class VideoNode
{
public:
static VideoNode* create();
void initWithFile(const std::string &fileName);
void play(bool repeat);
cocos2d::Sprite* getSprite(){
return this->sprite;
}
private:
void splitMovie(const std::string fileName, std::vector<cv::Mat> &mVec);
void cvMat2ccImage(cv::Mat &src, cocos2d::Image &dst);
cocos2d::Sprite* sprite;
cocos2d::Animate *action;
};
실장 부분은
VideoNode.cpp
#include "VideoNode.h"
VideoNode* VideoNode::create()
{
VideoNode* node = new (std::nothrow)VideoNode();
return node;
}
void VideoNode::initWithFile(const std::string &fileName)
{
//MP4のfileNameから画像バッファを取得
std::vector<cv::Mat> images;
splitMovie(fileName, images);
// //アニメーションクラスの作成
auto animation = cocos2d::Animation::create();
//
// //ループでアニメーションクラスにaddSpriteFrameしていく
//
for (int i=0; i < images.size(); i++) {
//newで動的にImage分のメモリを確保
cocos2d::Image *img = new cocos2d::Image();
cv::Mat m = images[i];
//確保したimgのアドレスの中身を渡す。
cvMat2ccImage(m, *img);
cocos2d::Texture2D *tex = new cocos2d::Texture2D();
tex->initWithImage(img);
auto rect = new cocos2d::Rect();
rect->setRect(0, 0, img->getWidth(), img->getHeight());
cocos2d::SpriteFrame *frame = cocos2d::SpriteFrame::createWithTexture(tex, *rect);
if(i==0){
cocos2d::Sprite *sprite = cocos2d::Sprite::createWithSpriteFrame(frame);
sprite->setName("animSprite");
this->sprite = sprite;
}
animation->addSpriteFrame(frame);
}
action = cocos2d::Animate::create(animation);
}
void VideoNode::play(bool repeat)
{
auto anime = cocos2d::RepeatForever::create(action);
this->sprite->runAction(anime);
}
//cvMatからcocos2d::Imageに変換するメソッド
void VideoNode::cvMat2ccImage(cv::Mat &src, cocos2d::Image &dst)
{
unsigned char *srcData;
int width = src.cols;
int height = src.rows;
srcData = (unsigned char *)src.data;
unsigned long size = 3 * width * height;
dst.initWithRawData(srcData, size, width, height, 24);
}
//映像からcv::Matのデータ群を取得するメソッド
void VideoNode::splitMovie(const std::string fileName, std::vector<cv::Mat> &mVec)
{
CvCapture *capture = cvCreateFileCapture(fileName.c_str());
if(!capture)
{
std::cerr << "cvCreateFileCapure filed" << std::endl;
}
int rows = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int cols = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
IplImage *frame =NULL;
cv::Mat m(rows, cols, CV_8UC3);
while ((frame=cvQueryFrame(capture))!=NULL) {
m = cv::cvarrToMat(frame);
mVec.push_back(m);
}
}
같은 느낌으로 구현해 보았습니다. 이것으로 갈 수 있다! 나는 생각했다.
왜, 아무것도 표시되지 않습니다! ?
콘솔을 보면 뭔가 warning이 나온다.
jpeg error: Wrong JPEG library version: library is 62, caller expects 90
size=0
라든지,
libpng warning: Application built with libpng-1.6.16 but running with 1.5.12
어쨌든 ....
아무래도 조사해 보면 OpenCV에서는 빌드시에 libpng 1.5.12 사용하고, cocos2d-x는 libpng 1.6.16 사용하고 있는 것이 원인인 것 같다.
하지만 iOS 용으로 OpenCV 빌드를 다시하면 갈 수 있을까? 라고 생각했지만 libpng와 libjpeg 어떻게 지정하면 좋은지 모르고 결국 할 수 없어.
되었습니다.
누군가 좋은 해결책이 있으면 꼭 알려주세요.
2015.6.14 추가
해결책과 코드를 수정한 것 정리했으므로
여기 을 참조하십시오.
Reference
이 문제에 관하여(Cocos2d-x에서 OpenCV를 사용하고 싶었지만 ...), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Hare8563/items/bae7ac731535215acd54텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)