2015-03-13 16 views
1

Я унаследовал программу MFC Windows CE старой школы, и мне нужно внести в нее некоторые изменения. В рамках этого я должен создать монохромное изображение с текстом на нем, и оба отображать его на экране, а также отправлять каждую строку изображения на принтер по одному.Создание, отображение, а затем доступ к данным растрового изображения/DIB (без GetBitmapBits())

Первоначально я использовал растровое изображение и имел успех с использованием DrawText() и получал тестовую строку (Hello World) для отображения на экране (этот код показан на рисунке 1). Тем не менее, я ударил стену на этапе, где я ищу, чтобы извлечь данные об обертке из растрового изображения. Я пытаюсь получить массив с 1 или 0, представляющий черный или белый. Я сначала думал, что буду использовать GetBitmapBits(), но, к сожалению, код, с которым я работаю, настолько старый, что функция еще не поддерживается. Я думал, что обойти эту проблему можно с помощью GetBitmap(), а затем доступа к параметру bmBits. Однако это всегда имеет значение null, которое было подтверждено, когда я нашел следующую ссылку: Why does GetObject return an BITMAP with null bmBits?.

Моя следующая попытка состояла в том, чтобы следовать рекомендациям по ссылке и использовать CreateDIBSection() вместо CreateCompatibleBitmap(). Это похоже на правильный путь, и у меня должен быть доступ к данным, которые я хочу, но, к сожалению, я не могу заставить DIB отображать (код показан на рисунке 2). Я подозреваю, что я делаю что-то неправильно в создании заголовка DIB, но я не могу понять, что моя ошибка.

Если у кого-то есть предложения по способу доступа к данным в растровом изображении, или я вижу, что я делаю неправильно с 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); 

}

ответ

0

Итак, я внес два незначительных изменения в код 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); 

Я не имел шанс увидеть, если я могу получить доступ к данным изображения, но я мимо начальные вопросы сейчас. Спасибо всем, кто посмотрел на это, и если люди знают, как сделать первый (зависимый от устройства растровый) метод, мне было бы интересно узнать.

 Смежные вопросы

  • Нет связанных вопросов^_^