gpt4 book ai didi

c++ - 使用 Gdiplus::Graphics::DrawText 在黑色背景上绘制白色文本时出现问题

转载 作者:行者123 更新时间:2023-11-30 03:07:57 25 4
gpt4 key购买 nike

我正在尝试找到一种方法来使用 Gdiplus::Graphics.DrawString 方法来创建在黑色背景上具有白色文本的位图。

(为什么?因为我需要能够旋转文本,而 Gdiplus::Graphics 对象有 RotateTransform 可用于此。)

我编写了一个示例控制台应用程序,它演示了我在尝试在黑色矩形上绘制白色文本时看到的内容。 (代码贴在下面。)

有人知道我做错了什么吗?在此先感谢您的帮助。

////////////////////////

// DrawTextTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#pragma comment (lib,"Gdiplus.lib")
#include <Windows.h>
#include <GdiPlusEnums.h>
#include <GdiPlusTypes.h>
#include <GdiPlus.h>
#include <iostream>
#include <string>

using namespace Gdiplus;
using namespace std;

bool RunTheTest(string);
bool SaveBitmapToFile(HDC, HBITMAP, BITMAPINFO&, string);
bool WriteBitmapFile(BYTE*, BITMAPINFOHEADER&, LPCTSTR);
void ShowError();

#define BUFFER_SIZE 1024

int _tmain(int argc, _TCHAR* argv[])
{
bool bRet(false);
char szBuff[BUFFER_SIZE];
size_t retVal;
string sFileName, sUserInput;
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;

if (argc > 1)
{
for (int nArg = 1; nArg < argc; nArg++)
{
wcstombs_s(&retVal, szBuff, (size_t)BUFFER_SIZE, argv[nArg], (size_t)BUFFER_SIZE );
if (nArg > 1)
sFileName += " ";
sFileName += szBuff;
}
}
else
{
cout << "Input the full path filename (do not enclose in quotes)" << endl;
cin >> sUserInput;
sFileName += sUserInput;
}
Status s = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
bRet = RunTheTest(sFileName);
GdiplusShutdown(gdiplusToken);
if (bRet)
return 0;
return 1;
}

bool RunTheTest(string sfileName)
{
BITMAPINFO bitmapInfo;
bool bRet(false);
Brush* pBlackBrush = new SolidBrush(Gdiplus::Color::Black);
Brush* pWhiteBrush = new SolidBrush(Gdiplus::Color::White);
double inchesPerMeter(39.3700787);
float fontSize(30);
Font* pFont(NULL);
FontFamily* pFontFamily(NULL);
FontStyle fs(FontStyleRegular);
HBITMAP hMemoryBitmap(NULL);
HDC hMemoryDC(NULL);
HGDIOBJ hDefaultBitmap(NULL);
int pelsPerMeter(0), resolution(240);
int oldBkMode(0);
LPTSTR pFileName(NULL);
PointF origin(0, 0);
SIZE sizeRect;
Status s;

// Initialize a memory device context compatible with the screen
hMemoryDC = CreateCompatibleDC(NULL);

// Prepare some values for creating a memory bitmap
pelsPerMeter = (int)(resolution * inchesPerMeter);
sizeRect.cx = sizeRect.cy = 400;

// Create the memory bitmap
bitmapInfo.bmiHeader.biBitCount = 24;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biXPelsPerMeter = pelsPerMeter;
bitmapInfo.bmiHeader.biYPelsPerMeter = pelsPerMeter;
bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo.bmiHeader);
bitmapInfo.bmiHeader.biWidth = sizeRect.cx;
bitmapInfo.bmiHeader.biHeight = sizeRect.cy;
hMemoryBitmap = CreateCompatibleBitmap(hMemoryDC, sizeRect.cx, sizeRect.cy);
hDefaultBitmap = SelectObject(hMemoryDC, hMemoryBitmap);

// Draw a white rectangle on the bitmap
SelectObject(hMemoryDC, GetStockObject(WHITE_BRUSH));
Rectangle(hMemoryDC, 0, 0, sizeRect.cx, sizeRect.cy);
SelectObject(hMemoryDC, GetStockObject(NULL_BRUSH));

// Set bitmap background mode to transparent mode
oldBkMode = SetBkMode(hMemoryDC, TRANSPARENT);

// Get a Graphics object from the memory device context
Graphics graphics(hMemoryDC);

// draw a black rectangle on the bitmap
s = graphics.FillRectangle(pBlackBrush, 0, 0, 400, 400);
if (s != Ok)
{
cout << "FillRectangle failed" << endl;
return false;
}

// draw white text on the black rectangle using the font we created
s = graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
if (s != Ok)
{
cout << "SetTextRenderingHint failed" << endl;
return false;
}

// Create a font object and draw the text on the bitmap
pFontFamily = new FontFamily(L"Arial");
if (pFontFamily == NULL)
{
cout << "new FontFamily failed" << endl;
return false;
}
pFont = new Font(pFontFamily, fontSize, fs);
if (pFont == NULL)
{
cout << "new Font failed" << endl;
if (pFontFamily != NULL)
delete pFontFamily;
return false;
}

s = graphics.DrawString(L"TEST STRING", 11, pFont, origin, pWhiteBrush);
if (s == Ok)
{ // Save the bitmap to a file
bRet = SaveBitmapToFile(hMemoryDC, hMemoryBitmap, bitmapInfo, sfileName);
}

// Clean up
SetBkMode(hMemoryDC, oldBkMode);
if (pFont != NULL)
delete pFont;
if (pFontFamily != NULL)
delete pFontFamily;
if (hDefaultBitmap != NULL && hMemoryBitmap != NULL)
SelectObject(hMemoryDC, hDefaultBitmap);
if (hMemoryBitmap != NULL)
DeleteObject(hMemoryBitmap);
if (hMemoryDC != NULL)
DeleteDC(hMemoryDC);
return bRet;
}

bool SaveBitmapToFile(HDC hMemoryDC, HBITMAP hMemoryBitmap, BITMAPINFO& bitmapInfo, string sFileName)
{
bool bRet(false);
DWORD dwBmpSize(0);
BYTE* pBytes(NULL);
ULONG ulcb(0);
WCHAR wchBuff[BUFFER_SIZE];
PSTR pTemp = (PSTR)wchBuff;

for (unsigned int nChar = 0; nChar < sFileName.length(); nChar++)
{
*pTemp++ = sFileName[nChar];
*pTemp++ = 0;
}
*pTemp++ = 0;
*pTemp = 0;

dwBmpSize = ((bitmapInfo.bmiHeader.biWidth * bitmapInfo.bmiHeader.biBitCount + 31) / 32) * 4 * bitmapInfo.bmiHeader.biHeight;
pBytes = new BYTE[dwBmpSize];
bRet = (GetDIBits(hMemoryDC, hMemoryBitmap, 0, bitmapInfo.bmiHeader.biHeight, &pBytes[0], &bitmapInfo, DIB_RGB_COLORS) != 0);
if (bRet)
bRet = WriteBitmapFile(pBytes, bitmapInfo.bmiHeader, wchBuff);
if (pBytes != NULL)
{
delete[] pBytes;
pBytes = NULL;
}
return bRet;
}

bool WriteBitmapFile(BYTE* pBitmapBits, BITMAPINFOHEADER& bmpInfoHeader, LPCTSTR lpszFileName)
{
BITMAPFILEHEADER bfh = {0};
bool bRet(false);
DWORD dwcb2Write(0), dwcbWritten(0);

// This value should be values of BM letters i.e 0×4D42
// 0x4D = M 0x42 = B storing in reverse order to match with endian
bfh.bfType=0x4D42;
// or...
// bfh.bfType = ‘B’+(’M’ << 8);
// <<8 used to shift ‘M’ to end

// Offset to the RGBQUAD
bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
bfh.bfSize = bfh.bfOffBits + bmpInfoHeader.biSizeImage;

HANDLE hFile = CreateFile(lpszFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "CreateFile failed" << endl;
ShowError();
return false;
}
dwcb2Write = sizeof(bfh);
bRet = (WriteFile(hFile, &bfh, dwcb2Write, &dwcbWritten, NULL) != 0);
if (!bRet || (dwcbWritten != dwcb2Write))
{
cout << "WriteFile failed" << endl;
ShowError();
CloseHandle(hFile);
return false;
}
dwcb2Write = sizeof(bmpInfoHeader);
bRet = (WriteFile(hFile, &bmpInfoHeader, dwcb2Write, &dwcbWritten, NULL) != 0);
if (!bRet || (dwcbWritten != dwcb2Write))
{
cout << "WriteFile failed" << endl;
ShowError();
CloseHandle(hFile);
return false;
}
dwcb2Write = bmpInfoHeader.biSizeImage;
bRet = (WriteFile(hFile, pBitmapBits, dwcb2Write, &dwcbWritten, NULL) != 0);
if (!bRet || (dwcbWritten != dwcb2Write))
{
cout << "WriteFile failed" << endl;
ShowError();
CloseHandle(hFile);
return false;
}
CloseHandle(hFile);
return true;
}

void ShowError()
{ // Retrieve the system error message for the last-error code
char szBuff[BUFFER_SIZE];
LPTSTR lpMsgBuf;
size_t retVal;
DWORD dw = GetLastError(), dwRet(0);

dwRet = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

wcstombs_s(&retVal, szBuff, (size_t)BUFFER_SIZE, lpMsgBuf, (size_t)BUFFER_SIZE );

// Display the error message
cout << szBuff << endl;

LocalFree(lpMsgBuf);
}

最佳答案

只需先使用 Graphics::FillRectangle() 绘制矩形。从 Graphics::MeasureString() 获取所需的矩形大小。

关于c++ - 使用 Gdiplus::Graphics::DrawText 在黑色背景上绘制白色文本时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5503649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com