首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将CBitmap转换为cv::Mat?

如何将CBitmap转换为cv::Mat?
EN

Stack Overflow用户
提问于 2018-02-06 20:28:55
回答 1查看 1K关注 0票数 0

如何将CBitmap转换为cv::Mat?也许有一些白痴或者别的什么..。比如..。

代码语言:javascript
复制
CBitmap bitmap;
bitmap.CreateBitmap(128, 128, 1, 24, someData);
cv::Mat outBitmap(128,128,someData,1,24);

但是那个代码是不正确的。

谢谢!

EN

回答 1

Stack Overflow用户

发布于 2018-02-07 11:01:31

还有另一种方法,您可以将CBitmap转换为HBitmap,然后将HBitmap转换为GdiPlus::Bitmap,然后将其转换为cv::Mat。您可以这样做,但请注意,此解决方案仅适用于RGB24像素格式:

步骤1: CBitmap to HBITMAP

代码语言:javascript
复制
HBITMAP hBmp = (HBITMAP)yourCBitmap.GetSafeHandle();

步骤2: HBITMAP to Gdiplus::Bitmap (从this问题复制)

代码语言:javascript
复制
#include <GdiPlus.h>
#include <memory>

Gdiplus::Status HBitmapToBitmap( HBITMAP source, Gdiplus::PixelFormat pixel_format, Gdiplus::Bitmap** result_out )
{
  BITMAP source_info = { 0 };
  if( !::GetObject( source, sizeof( source_info ), &source_info ) )
    return Gdiplus::GenericError;

  Gdiplus::Status s;

  std::auto_ptr< Gdiplus::Bitmap > target( new Gdiplus::Bitmap( source_info.bmWidth, source_info.bmHeight, pixel_format ) );
  if( !target.get() )
    return Gdiplus::OutOfMemory;
  if( ( s = target->GetLastStatus() ) != Gdiplus::Ok )
    return s;

  Gdiplus::BitmapData target_info;
  Gdiplus::Rect rect( 0, 0, source_info.bmWidth, source_info.bmHeight );

  s = target->LockBits( &rect, Gdiplus::ImageLockModeWrite, pixel_format, &target_info );
  if( s != Gdiplus::Ok )
    return s;

  if( target_info.Stride != source_info.bmWidthBytes )
    return Gdiplus::InvalidParameter; // pixel_format is wrong!

  CopyMemory( target_info.Scan0, source_info.bmBits, source_info.bmWidthBytes * source_info.bmHeight );

  s = target->UnlockBits( &target_info );
  if( s != Gdiplus::Ok )
    return s;

  *result_out = target.release();

  return Gdiplus::Ok;
}

调用此函数并将您的HBITMAP传递给它。

步骤3: Gdiplus::Bitmap to cv::Mat

代码语言:javascript
复制
cv::Mat GdiPlusBitmapToCvMat(Gdiplus::Bitmap* bmp)
{
    auto format = bmp->GetPixelFormat();
    if (format != PixelFormat24bppRGB)
        return cv::Mat();

    int width = bmp->GetWidth();
    int height = bmp->GetHeight();
    Gdiplus::Rect rcLock(0, 0, width, height);
    Gdiplus::BitmapData bmpData;

    if (!bmp->LockBits(&rcLock, Gdiplus::ImageLockModeRead, format, &bmpData) == Gdiplus::Ok)
        return cv::Mat();

    cv::Mat mat = cv::Mat(height, width, CV_8UC3, static_cast<unsigned char*>(bmpData.Scan0), bmpData.Stride).clone();

    bmp->UnlockBits(&bmpData);
    return mat;
}

将您在最后一步创建的Gdiplus::Bitmap传递到此函数,您将得到您的cv:Mat。正如我之前说过的,这个函数只适用于RGB24像素格式。

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

https://stackoverflow.com/questions/48651448

复制
相关文章

相似问题

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