首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将cv::Mat转换为SDL_Texture

将cv::Mat转换为SDL_Texture
EN

Stack Overflow用户
提问于 2014-03-28 01:41:00
回答 2查看 2.9K关注 0票数 4

我试着用SDL播放一段视频。为此,我使用opencv加载视频,并获取帧。然后,我只需要转换这些帧,因为我需要它们成为一个SDL_Texture*,我已经准备好在屏幕上绘制它们。

这是我的问题,我正在把它转换成SDL_Surface*,但是到SDL_Texture的转换失败了,我不知道为什么。这是我的代码:

代码语言:javascript
运行
复制
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,它在那里工作。所以问题是:您知道我在代码中进行的转换有什么问题吗?如果没有,有没有更好的方法来做我想做的事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-28 14:28:32

我让它开始工作了!我认为唯一的问题是我必须使用&frameMat,而不是frameMat。这是我的代码,如果有人感兴趣的话:

代码语言:javascript
运行
复制
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);

}

票数 7
EN

Stack Overflow用户

发布于 2020-03-27 02:47:11

下面是另一种不使用IplImage的方法

代码语言:javascript
运行
复制
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创建纹理,然后更新它。这导致了灰色条纹和图像的混乱。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22702630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档