单色位图 C++ GDIPlus

发布于 2024-11-02 22:33:26 字数 3284 浏览 1 评论 0原文

我目前在向表单显示单色位图时遇到问题。我相信我的位图设置不正确,但我目前看不到它在哪里。要“修复”此问题,我所需要做的就是将 biBitCount 设置为 24,但是当我稍后调用 DWORD d = GetCharacterPlacementA 时,我会看到后者的内存已损坏。所以我试图保持我最初对单色位图的渴望,而不是泄漏内存。

目前,我将位图信息存储在标准变量中:

BITMAPINFO bi24BitInfo;
HDC hMemoryDC;
HBITMAP hMemoryBitmap;
HGDIOBJ hDefaultBitmap;
HBITMAP hGdiBitmap;

这就是我设置位图的方式:

hMemoryDC = CreateCompatibleDC(NULL);

bi24BitInfo.bmiHeader.biSize = sizeof(bi24BitInfo.bmiHeader);   // size of this struct
bi24BitInfo.bmiHeader.biWidth = 600;//sizeRect.cx;      // width of window
bi24BitInfo.bmiHeader.biHeight = 600;//sizeRect.cy; // height of window
bi24BitInfo.bmiHeader.biPlanes = 1;
bi24BitInfo.bmiHeader.biBitCount = 1;               // monochrome // rgb 8 bytes for each component(3)
bi24BitInfo.bmiHeader.biCompression = BI_RGB;   // Means its uncompressed. Has nothing to do with color.
bi24BitInfo.bmiHeader.biSizeImage = 0;
bi24BitInfo.bmiHeader.biXPelsPerMeter = pelsPerMeter;
bi24BitInfo.bmiHeader.biYPelsPerMeter = pelsPerMeter;
bi24BitInfo.bmiHeader.biClrUsed = 2;
bi24BitInfo.bmiHeader.biClrImportant = 0;
bi24BitInfo.bmiColors[0].rgbBlue = 0;
bi24BitInfo.bmiColors[0].rgbRed = 0;
bi24BitInfo.bmiColors[0].rgbGreen = 0;
bi24BitInfo.bmiColors[0].rgbReserved = 0;
bi24BitInfo.bmiColors[1].rgbBlue = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbRed = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbGreen = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbReserved = 0;

// Create the memory bitmap
if (hMemoryBitmap != NULL)
{
    DeleteObject(hMemoryBitmap);
}
hMemoryBitmap = CreateCompatibleBitmap(hMemoryDC, 600, 600);
hDefaultBitmap = SelectObject(hMemoryDC, hMemoryBitmap);
HGDIOBJ hOldFont = SelectObject(hMemoryDC, GetStockObject(NULL_BRUSH));
// Do not fill background
int nOldBkMode = GetBkMode(hMemoryDC);
SetBkMode(hMemoryDC, TRANSPARENT);

int nRet(0);

if (hDIB != NULL)
{
    GlobalFree(hDIB);
}
DWORD dwBmpSize = ((bi24BitInfo.bmiHeader.biWidth * bi24BitInfo.bmiHeader.biBitCount + 31) / 32) * 4 * bi24BitInfo.bmiHeader.biHeight;
//DWORD dwBmpSize = ((bi24BitInfo.bmiHeader.biWidth * bi24BitInfo.bmiHeader.biHeight)/8);
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that call HeapAlloc using a handle
// to the process's default heap. Therefore, GlobalAlloc and LocalAlloc have greater overhead than HeapAlloc.
hDIB = GlobalAlloc(GHND, dwBmpSize);
DWORD D = GetLastError();
pBytes = (BYTE*)GlobalLock(hDIB);
D = GetLastError();
nRet = GetDIBits(hMemoryDC, hMemoryBitmap, 0, (UINT)bi24BitInfo.bmiHeader.biHeight, pBytes, (BITMAPINFO*)&bi24BitInfo, DIB_RGB_COLORS);
D = GetLastError();
if (pBitmap != NULL)
{
    delete pBitmap;
    pBitmap = NULL;
}
pBitmap = new Gdiplus::Bitmap(&bi24BitInfo, pBytes);
D = GetLastError();
GlobalUnlock(hDIB);
D = GetLastError();

然后在完成所有这些之后,我收到以下错误:

pGraphics = Graphics::FromImage(pBitmap);
// set a graphics property
s = pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias);

在此之后,pGraphics->LastResult 现在设置为“ OutOfMemory”并且 s 设置为枚举“InvalidParameter”:http://msdn.microsoft.com/en-us/ library/ms534175(v=VS.85).aspx

对此的任何帮助将不胜感激。

I'm currently having issues displaying a monochrome bitmap to my form. I belive that somehow I am setting up my bitmap incorrectly, but I can't see where that would be at the moment. All I have to do to "fix" this issue is set the biBitCount to 24, but then when I call DWORD d = GetCharacterPlacementA latter on I'm seeing corrupted memory latter on. So I'm trying to keep my original desire for a monochrome bitmap and not leak memory.

Currently I'm storing my bitmap information in the standard variables:

BITMAPINFO bi24BitInfo;
HDC hMemoryDC;
HBITMAP hMemoryBitmap;
HGDIOBJ hDefaultBitmap;
HBITMAP hGdiBitmap;

This is how I am setting up the bitmap:

hMemoryDC = CreateCompatibleDC(NULL);

bi24BitInfo.bmiHeader.biSize = sizeof(bi24BitInfo.bmiHeader);   // size of this struct
bi24BitInfo.bmiHeader.biWidth = 600;//sizeRect.cx;      // width of window
bi24BitInfo.bmiHeader.biHeight = 600;//sizeRect.cy; // height of window
bi24BitInfo.bmiHeader.biPlanes = 1;
bi24BitInfo.bmiHeader.biBitCount = 1;               // monochrome // rgb 8 bytes for each component(3)
bi24BitInfo.bmiHeader.biCompression = BI_RGB;   // Means its uncompressed. Has nothing to do with color.
bi24BitInfo.bmiHeader.biSizeImage = 0;
bi24BitInfo.bmiHeader.biXPelsPerMeter = pelsPerMeter;
bi24BitInfo.bmiHeader.biYPelsPerMeter = pelsPerMeter;
bi24BitInfo.bmiHeader.biClrUsed = 2;
bi24BitInfo.bmiHeader.biClrImportant = 0;
bi24BitInfo.bmiColors[0].rgbBlue = 0;
bi24BitInfo.bmiColors[0].rgbRed = 0;
bi24BitInfo.bmiColors[0].rgbGreen = 0;
bi24BitInfo.bmiColors[0].rgbReserved = 0;
bi24BitInfo.bmiColors[1].rgbBlue = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbRed = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbGreen = (BYTE)0xFF;
bi24BitInfo.bmiColors[1].rgbReserved = 0;

// Create the memory bitmap
if (hMemoryBitmap != NULL)
{
    DeleteObject(hMemoryBitmap);
}
hMemoryBitmap = CreateCompatibleBitmap(hMemoryDC, 600, 600);
hDefaultBitmap = SelectObject(hMemoryDC, hMemoryBitmap);
HGDIOBJ hOldFont = SelectObject(hMemoryDC, GetStockObject(NULL_BRUSH));
// Do not fill background
int nOldBkMode = GetBkMode(hMemoryDC);
SetBkMode(hMemoryDC, TRANSPARENT);

int nRet(0);

if (hDIB != NULL)
{
    GlobalFree(hDIB);
}
DWORD dwBmpSize = ((bi24BitInfo.bmiHeader.biWidth * bi24BitInfo.bmiHeader.biBitCount + 31) / 32) * 4 * bi24BitInfo.bmiHeader.biHeight;
//DWORD dwBmpSize = ((bi24BitInfo.bmiHeader.biWidth * bi24BitInfo.bmiHeader.biHeight)/8);
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that call HeapAlloc using a handle
// to the process's default heap. Therefore, GlobalAlloc and LocalAlloc have greater overhead than HeapAlloc.
hDIB = GlobalAlloc(GHND, dwBmpSize);
DWORD D = GetLastError();
pBytes = (BYTE*)GlobalLock(hDIB);
D = GetLastError();
nRet = GetDIBits(hMemoryDC, hMemoryBitmap, 0, (UINT)bi24BitInfo.bmiHeader.biHeight, pBytes, (BITMAPINFO*)&bi24BitInfo, DIB_RGB_COLORS);
D = GetLastError();
if (pBitmap != NULL)
{
    delete pBitmap;
    pBitmap = NULL;
}
pBitmap = new Gdiplus::Bitmap(&bi24BitInfo, pBytes);
D = GetLastError();
GlobalUnlock(hDIB);
D = GetLastError();

Then after all of this I'm getting an error in the following:

pGraphics = Graphics::FromImage(pBitmap);
// set a graphics property
s = pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias);

After this pGraphics->LastResult is now set to "OutOfMemory" and s is set to the enum "InvalidParameter" from: http://msdn.microsoft.com/en-us/library/ms534175(v=VS.85).aspx

Any help on this would be appriciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半衬遮猫 2024-11-09 22:33:27

BITMAPINFO 仅包含一个调色板条目的空间;当您写入 bi24BitInfo.bmiColors[1] 时,您会破坏后面的内存,例如 hMemoryDC。通过创建另一个结构来修复此问题,该结构在前面包含 BITMAPINFO ,并在后面包含一个调色板数组。

编辑:您似乎无法从单色位图创建 Graphics 对象。来自 Graphics::FromImage 文档:

如果图像
具有以下像素之一
格式:

  • PixelFormat未定义
  • PixelFormatDontCare
  • PixelFormat1bppIndexed
  • PixelFormat4bppIndexed
  • PixelFormat8bppIndexed
  • PixelFormat16bppGrayScale
  • PixelFormat16bppARGB1555

BITMAPINFO only contains room for one palette entry; when you write to bi24BitInfo.bmiColors[1] you're clobbering the memory that follows, likely the hMemoryDC. Fix this by creating another structure that contains BITMAPINFO at the front and an array for the palette following.

Edit: It appears you aren't able to create a Graphics object from a monochrome bitmap. From the Graphics::FromImage documentation:

This method also fails if the image
has one of the following pixel
formats:

  • PixelFormatUndefined
  • PixelFormatDontCare
  • PixelFormat1bppIndexed
  • PixelFormat4bppIndexed
  • PixelFormat8bppIndexed
  • PixelFormat16bppGrayScale
  • PixelFormat16bppARGB1555
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文