gpt4 book ai didi

c++ - 创建、显示然后访问位图/DIB 数据(w/o GetBitmapBits())

转载 作者:太空宇宙 更新时间:2023-11-04 13:37:36 26 4
gpt4 key购买 nike

我继承了一个老式的 MFC Windows CE 程序,我不得不对其进行一些修改。作为其中的一部分,我必须创建一个带有文本的单色图像,并将其显示在屏幕上,并将图像的每一行一次一个地发送到打印机。

我最初使用位图,并成功使用 DrawText() 并获得了一个测试字符串 (Hello World) 以显示在屏幕上(此代码在图 1 中)。但是,我在寻找从位图中提取环绕数据的阶段遇到了困难。我想要得到的是一个数组,其中 1 或 0 代表黑色或白色。我最初以为我会使用 GetBitmapBits() 但不幸的是,我正在使用的代码太旧了,尚不支持该功能。我想我可以通过使用 GetBitmap() 然后访问 bmBits 参数来解决这个问题。然而,这似乎总是空的,当我找到以下链接时得到确认:Why does GetObject return an BITMAP with null bmBits? .

我的下一次尝试是按照链接中的建议使用 CreateDIBSection() 而不是 CreateCompatibleBitmap()。这似乎是正确的路径,我应该可以访问我想要的数据,但遗憾的是我无法显示 DIB(代码在图 2 中)。我怀疑我在创建 DIB header 时做错了什么,但我无法弄清楚我的错误是什么。

如果有人对访问位图中数据的方法有建议,或者可以看到我在使用 DIB 时做错了什么,我将不胜感激!

*** 图 1:创建和显示位图的代码

void CRunPage::OnPaint() 
{
CPaintDC dc(this); // property page device context for painting
CBitmap mBmp; // CBitmap object for displaying built-in bitmaps
CDC mDCMem; // CDC object to handle built-in bitmap
int iWidth, iHeight; // dimension to draw on the screen

int icurLabel, // current label index of open print file
iLabelNum; // number of labels in open print file
LPBITMAPINFOHEADER pBMIH; // bitmap header object for current label
LPBYTE pImage; // bitmap data for current label
CSize size; // size of label
int PreviewLeft,PreviewTop,PreviewWidth,PreviewHeight;
CRect Rect;
BITMAP bm;
LPVOID bmBits=NULL;

// Calculate the preview area
PreviewLeft=5;
PreviewTop=5;
GetDlgItem(IDC_RUN_NEXT)->GetWindowRect(&Rect);
ScreenToClient(&Rect);
PreviewWidth=Rect.left-PreviewLeft*2;
GetDlgItem(IDC_RUN_WRAPTEXT)->GetWindowRect(&Rect);
ScreenToClient(&Rect);
PreviewHeight=Rect.top-PreviewTop*2;

CRect textRect;
CString testText(_T("Hello World"));

CBitmap * pOldBitmap;
CBrush whiteBrush, *pOldBrush;
CPen blackPen, *pOldPen;


mDCMem.CreateCompatibleDC(&dc);

mBmp.CreateCompatibleBitmap(&dc, PreviewWidth+PreviewLeft*2, PreviewHeight+PreviewTop*2);
//mBmp.CreateCompatibleBitmap(&dc, PreviewWidth, PreviewHeight);
pOldBitmap = mDCMem.SelectObject(&mBmp);

blackPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
whiteBrush.CreateSolidBrush(RGB(255,255,255));

textRect.SetRect(0,0,PreviewWidth, PreviewHeight);

// this means behind the text will be a white box w/ a black boarder
pOldBrush = mDCMem.SelectObject(&whiteBrush);
pOldPen = mDCMem.SelectObject(&blackPen);

//these commands draw on the memory-only context (mDCMem)
mDCMem.Rectangle(&textRect);
mDCMem.DrawText((LPCTSTR)testText, 11, &textRect, DT_CENTER|DT_VCENTER);

mDCMem.SelectObject(pOldBrush);
mDCMem.SelectObject(pOldPen);

dc.StretchBlt(PreviewLeft,PreviewTop, PreviewWidth, PreviewHeight, & mDCMem, 0, 0, PreviewWidth, PreviewHeight, SRCCOPY);

mDCMem.SelectObject(pOldBitmap);

}

*** 图 2:尝试使用 DIB 而不是位图

void CRunPage::OnPaint() 
{

CPaintDC dc(this); // property page device context for painting

CBitmap mBmp; // CBitmap object for displaying built-in bitmaps
CDC mDCMem; // CDC object to handle built-in bitmap
int iWidth, iHeight; // dimension to draw on the screen

int icurLabel, // current label index of open print file
iLabelNum; // number of labels in open print file
LPBITMAPINFOHEADER pBMIH; // bitmap header object for current label
LPBYTE pImage; // bitmap data for current label
CSize size; // size of label
int PreviewLeft,PreviewTop,PreviewWidth,PreviewHeight;
CRect Rect;
BITMAP bm;

// Calculate the preview area
PreviewLeft=5;
PreviewTop=5;
GetDlgItem(IDC_RUN_NEXT)->GetWindowRect(&Rect);
ScreenToClient(&Rect);
PreviewWidth=Rect.left-PreviewLeft*2;
GetDlgItem(IDC_RUN_WRAPTEXT)->GetWindowRect(&Rect);
ScreenToClient(&Rect);
PreviewHeight=Rect.top-PreviewTop*2;

CRect textRect;
CString testText(_T("Hello World"));

CBitmap * pOldBitmap;
CBrush whiteBrush, *pOldBrush;
CPen blackPen, *pOldPen;

LPBYTE pFWandImageMem=NULL, pImageMem=NULL, pTemp=NULL;
int i=0,j=0, buffSize=0, numBytesPerRow=0, bitmapWidthPix,bitmapHeightPix;

char *numBytesPerRowString;
char temp;
void ** ppvBits;
BITMAPINFOHEADER bmif;
BITMAPINFO bmi;
HBITMAP myDIB, myOldDIB;

mDCMem.CreateCompatibleDC(&dc);

//this rect is the area in which I can draw (its x,y location is set by BitBlt or StretchBlt
//mBmp.CreateCompatibleBitmap(&dc, PreviewWidth+PreviewLeft*2, PreviewHeight+PreviewTop*2);

bmif.biSize = sizeof(BITMAPINFOHEADER);
bmif.biWidth = PreviewWidth+PreviewLeft*2;
bmif.biHeight = -(PreviewHeight+PreviewTop*2);//- means top down (I think? I tried both ways and neither worked)
bmif.biPlanes = 1;
bmif.biBitCount = 1;
bmif.biCompression = BI_RGB; // no compression
bmif.biSizeImage = 0; // Size (bytes) if image - this can be set to 0 for uncompressed images
bmif.biXPelsPerMeter = 0;
bmif.biYPelsPerMeter = 0;
bmif.biClrUsed =0;
bmif.biClrImportant = 0;

bmi.bmiColors[0].rgbBlue=0;
bmi.bmiColors[0].rgbGreen=0;
bmi.bmiColors[0].rgbRed=0;
bmi.bmiColors[0].rgbReserved=0;
bmi.bmiColors[1].rgbBlue=255;
bmi.bmiColors[1].rgbGreen=255;
bmi.bmiColors[1].rgbRed=255;
bmi.bmiColors[1].rgbReserved=0;

bmi.bmiHeader=bmif;

myDIB = CreateDIBSection(dc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);

myOldDIB = (HBITMAP)mDCMem.SelectObject(myDIB);//SelectObject(mDCMem, myDIB);
blackPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
whiteBrush.CreateSolidBrush(RGB(255,255,255));

textRect.SetRect(0,0,PreviewWidth, PreviewHeight);

// this means behind the text will be a white box w/ a black boarder
pOldBrush = mDCMem.SelectObject(&whiteBrush);
pOldPen = mDCMem.SelectObject(&blackPen);

//these commands draw on the memory-only context (mDCMem)
mDCMem.Rectangle(&textRect);
mDCMem.DrawText((LPCTSTR)testText, 11, &textRect, DT_CENTER|DT_VCENTER);

mDCMem.SelectObject(pOldBrush);
mDCMem.SelectObject(pOldPen);

dc.StretchBlt(PreviewLeft,PreviewTop, PreviewWidth, PreviewHeight, & mDCMem, 0, 0, PreviewWidth, PreviewHeight, SRCCOPY);

mDCMem.SelectObject(myOldDIB);

最佳答案

所以我对 DIB 代码做了两个小改动,它现在可以正确显示图像了。

首先,我更改了将指针传递给 CreateDIBSection() 的方式:

void ** ppvBits;

LPBYTE pBits;

然后我不得不更改将其传递给 CreateDIBSection 的方式。我还明确地将 CreateDIBSection() 的返回值转换为 HBITMAP:

myDIB = CreateDIBSection(dc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);

myDIB = (HBITMAP) CreateDIBSection(dc.GetSafeHdc(), &bmi, DIB_RGB_COLORS, ppvBits, NULL, 0);

我还没有机会查看是否可以访问图像数据,但我现在已经解决了最初的问题。感谢所有看过此内容的人,如果有人知道如何执行第一种(设备相关位图)方法,我会很想知道。

关于c++ - 创建、显示然后访问位图/DIB 数据(w/o GetBitmapBits()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29034710/

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