我试着用SDL播放一段视频。为此,我使用opencv加载视频,并获取帧。然后,我只需要转换这些帧,因为我需要它们成为一个SDL_Texture*,我已经准备好在屏幕上绘制它们。
这是我的问题,我正在把它转换成SDL_Surface*,但是到SDL_Texture的转换失败了,我不知道为什么。这是我的代码:
void Cutscene::play()
{
this->onLoop();
this->onRender();
while(!frameMat.empty())
{
this->onLoop();
this->onRender();
}
}
void Cutscene::onLoop()
{
video >> frameMat;
convertCV_MatToSDL_Texture();
}
void Cutscene::onRender()
{
Image::onDraw(GameEngine::getInstance()->getRenderer(), frameTexture);
}
void Cutscene::convertCV_MatToSDL_Texture()
{
IplImage opencvimg2 = (IplImage)frameMat;
IplImage* opencvimg = &opencvimg2;
//Convert to SDL_Surface
frameSurface = SDL_CreateRGBSurfaceFrom((void*)opencvimg->imageData,
opencvimg->width, opencvimg->height,
opencvimg->depth*opencvimg->nChannels,
opencvimg->widthStep,
0xff0000, 0x00ff00, 0x0000ff, 0);
if(frameSurface == NULL)
{
SDL_Log("Couldn't convert Mat to Surface.");
return;
}
//Convert to SDL_Texture
frameTexture = SDL_CreateTextureFromSurface(
GameEngine::getInstance()->getRenderer(), frameSurface);
if(frameTexture == NULL)
{
SDL_Log("Couldn't convert Mat(converted to surface) to Texture."); //<- ERROR!!
return;
}
//cvReleaseImage(&opencvimg);
//MEMORY LEAK?? opencvimg opencvimg2
}我在我的项目的其他部分中使用了这个函数SDL_CreateTextureFromSurface,它在那里工作。所以问题是:您知道我在代码中进行的转换有什么问题吗?如果没有,有没有更好的方法来做我想做的事?
发布于 2014-03-28 14:28:32
我让它开始工作了!我认为唯一的问题是我必须使用&frameMat,而不是frameMat。这是我的代码,如果有人感兴趣的话:
SDL_Texture* Cutscene::convertCV_MatToSDL_Texture(const cv::Mat &matImg)
{
IplImage opencvimg2 = (IplImage)matImg;
IplImage* opencvimg = &opencvimg2;
//Convert to SDL_Surface
frameSurface = SDL_CreateRGBSurfaceFrom(
(void*)opencvimg->imageData,
opencvimg->width, opencvimg->height,
opencvimg->depth*opencvimg->nChannels,
opencvimg->widthStep,
0xff0000, 0x00ff00, 0x0000ff, 0);
if(frameSurface == NULL)
{
SDL_Log("Couldn't convert Mat to Surface.");
return NULL;
}
//Convert to SDL_Texture
frameTexture = SDL_CreateTextureFromSurface(
GameEngine::getInstance()->getRenderer(), frameSurface);
if(frameTexture == NULL)
{
SDL_Log("Couldn't convert Mat(converted to surface) to Texture.");
return NULL;
}
else
{
SDL_Log("SUCCESS conversion");
return frameTexture;
}
cvReleaseImage(&opencvimg);}
发布于 2020-03-27 02:47:11
下面是另一种不使用IplImage的方法
cv::Mat m ...;
// I'm using SDL_TEXTUREACCESS_STREAMING because it's for a video player, you should
// pick whatever suits you most: https://wiki.libsdl.org/SDL_TextureAccess
// remember to pick the right SDL_PIXELFORMAT_* !
SDL_Texture* tex = SDL_CreateTexture(
ren, SDL_PIXELFORMAT_BGR24, SDL_TEXTUREACCESS_STREAMING, m.cols,
m.rows);
SDL_UpdateTexture(tex, NULL, (void*)m.data, m.step1());
// do stuff with texture
SDL_RenderClear(...);
SDL_RenderCopy(...);
SDL_RenderPresent(...);
// cleanup (only after you're done displaying. you can repeatedly call UpdateTexture without destroying it)
SDL_DestroyTexture(tex)我更喜欢这种方法,因为您不需要释放曲面,而且它更灵活(例如,您可以轻松地更新纹理,而不是创建/破坏)。我还将注意到,我不能将这些方法结合起来:即用SDL_CreateRGBSurfaceFrom创建纹理,然后更新它。这导致了灰色条纹和图像的混乱。
https://stackoverflow.com/questions/22702630
复制相似问题