【问题标题】:Merging two Gdiplus::Bitmap into one c++将两个 Gdiplus::Bitmap 合并为一个 c++
【发布时间】:2013-07-22 20:32:35
【问题描述】:

我有两个位图:

Gdiplus::Bitmap *pbmBitmap, pbmBitmap1;

它们包含两个图像。如何将它们合并为一张图片?

我正在尝试这样的事情:

Bitmap* dstBitmap = new Bitmap(pbmBitmap->GetWidth(), pbmBitmap->GetHeight() + pbmBitmap1->GetHeight()); //create dst bitmap

HDC dcmem = CreateCompatibleDC(NULL);
SelectObject(dcmem, pbmBitmap); //select first bitmap

HDC dcmemDst = CreateCompatibleDC(NULL);
SelectObject(dcmem1, dstBitmap ); //select destination bitmap

BitBlt(dcmemDst em1, 0, 0, pbmBitmap->GetWidth(), pbmBitmap->GetHeight(), dcmem, 0, 0, SRCCOPY); //copy first bitmap into destination bitmap

HBITMAP CreatedBitmap = CreateCompatibleBitmap(dcmem, pbmBitmap->GetWidth(), pbmBitmap->GetHeight() + pbmBitmap1->GetHeight());

dstBitmap = new Bitmap(CreatedBitmap, NULL);
dstBitmap ->Save(L"omg.bmp", &pngClsid, 0); //pngClsid i took from msdn

我知道 - 丑陋的代码,但我需要用 C++ 来做。 我得到黑色图像。为什么?

//编辑

在谷歌搜索和阅读两个小时后,我得到了这个:

HBITMAP bitmapSource;
pbmBitmap->GetHBITMAP(Color::White, &bitmapSource); //create HBITMAP from Gdiplus::Bitmap

HDC dcDestination = CreateCompatibleDC(NULL); //create device contex for our destination bitmap
HBITMAP HBitmapDestination = CreateCompatibleBitmap(dcDestination, pbmBitmap->GetWidth(), pbmBitmap->GetHeight()); //create HBITMAP with correct size
SelectObject(dcDestination, dcDestination); //select created hbitmap on our destination dc

HDC dcSource = CreateCompatibleDC(NULL); //create device contex for our source bitmap
SelectObject(dcSource, bitmapSource); //select source bitmap on our source dc

BitBlt(dcDestination, 0, 0, pbmBitmap->GetWidth(), pbmBitmap->GetHeight(), dcSource, 0, 0, SRCCOPY); //copy piece of bitmap with correct size

SaveBitmap(dcDestination, HBitmapDestination, "OMG.bmp"); //not working i get 24kb bitmap
//SaveBitmap(dcSource, bitmapSource, "OMG.bmp"); //works like a boss, so it's problem with SaveBitmap function

它应该可以工作,但我得到 24kb 位图。 SaveBitmap 是我的自定义函数,当我尝试保存源位图时它可以工作。 为什么我不能将一个位图复制到另一个位图??

【问题讨论】:

  • 你在哪里加载原始位图?
  • 你的意思是pbmBitmap和pbmBitmap1?我一开始就加载它们。它们已正确加载。我使用保存检查了它。
  • 我已经有一段时间没有做这种事情了,但我建议检查所有操作的结果(BitBlt 和 SelectObject 返回非零并且 dcMem 和 dcMemDst 不为 NULL)
  • 看看我的编辑。我检查了每个电话。 SelectObject 返回的不是 NULL,所有 dc 也不是 NULL。 BitBlt 返回 TRUE。

标签: c++ bitmap merge gdi+


【解决方案1】:

使用 Graphics 对象来组合它们。这是一些示例工作代码...当然,您应该使用诸如 unique_ptr 之类的智能 ptr 而不是 new/delete,但我不想假设您使用的是 VS 2012 或更高版本。

void CombineImages()
{
    Status rc;

    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);

    Bitmap* bmpSrc1 = Bitmap::FromFile(L"Image1.JPG");
    assert(bmpSrc1->GetLastStatus() == Ok);
    Bitmap* bmpSrc2 = Bitmap::FromFile(L"Image2.JPG");
    assert(bmpSrc2->GetLastStatus() == Ok);

    Bitmap dstBitmap(bmpSrc1->GetWidth(), bmpSrc1->GetHeight() + bmpSrc2->GetHeight());
    assert(dstBitmap.GetLastStatus() == Ok);

    Graphics* g = Graphics::FromImage(&dstBitmap);
    rc = g->DrawImage(bmpSrc1, 0, 0 );
    assert(rc == Ok);
    rc = g->DrawImage(bmpSrc2, 0, bmpSrc1->GetHeight());
    assert(rc == Ok);

    rc = dstBitmap.Save(L"Output.png", &pngClsid, NULL);
    assert(rc == Ok);

    delete g;
    delete bmpSrc1;
    delete bmpSrc2;
}

主要功能..

int _tmain(int argc, _TCHAR* argv[])
{
    ULONG_PTR token;
    GdiplusStartupInput input;

    GdiplusStartup(&token, &input, nullptr);
    CombineImages();
    GdiplusShutdown(token);
    return 0;
}

【讨论】:

    【解决方案2】:

    这是我自己的函数,它接收图像文件的矢量并将它们垂直合并。

    wstring CombineBitmaps(矢量文件) { wstring NewFile{ L"Output.png" };

    Gdiplus::Status rc;
    
    CLSID pngClsid;
    GetEncoderClsid(L"image/png", &pngClsid);
    
    vector< Gdiplus::Bitmap*> bmpSrc;
    int Height{ 0 };
    for (int i = 0; i < files.size(); i++)
    {
        bmpSrc.push_back (Gdiplus::Bitmap::FromFile(files[i].c_str()));
        Height += bmpSrc[0]->GetHeight();
    } 
    Gdiplus::Bitmap dstBitmap(bmpSrc[0]->GetWidth(), Height);
    Gdiplus::Graphics* g = Gdiplus::Graphics::FromImage(&dstBitmap);
    for (int i = 0; i < files.size(); i++)
    {
        rc = g->DrawImage(bmpSrc[i], 0, i*bmpSrc[i]->GetHeight());
    }
    
    rc = dstBitmap.Save(NewFile.c_str(), &pngClsid, NULL);
    
    delete g;
    
    return NewFile;
    

    }

    你可以这样称呼它:

    vector<wstring> screens;
    screens.push_back(L"screenshot1");
    screens.push_back(L"screenshot2");
    screens.push_back(L"screenshot3");
    screens.push_back(L"screenshot4");
    screens.push_back(L"screenshot5");
    CombineBitmaps(screens);
    

    【讨论】:

      猜你喜欢
      • 2011-06-12
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多