Créer, afficher, puis accéder à des données bitmap / DIB (w / o GetBitmapBits ())

voix
1

J'ai hérité d'une vieille école de programme CE MFC de Windows, et je suis d'avoir à faire quelques modifications. Dans le cadre de ce que je dois créer une image monochrome avec texte, et afficher à la fois sur un écran ainsi que d'envoyer chaque ligne de l'image à une imprimante un à la fois.

J'utilisé à l' origine d' un bitmap, et eu du succès en utilisant DrawText () et obtenir une chaîne de test (Bonjour tout le monde) pour afficher à l'écran (ce code est à la figure 1). Cependant, je frappe un mur au stade où je suis à la recherche d'extraire les données d'enveloppe du bitmap. Ce que je suis en train de faire est un tableau avec 1 ou de 0 représentant le noir ou blanc. J'avais d' abord pensé que je pourrais utiliser GetBitmapBits () , mais malheureusement , le code , je travaille avec est si vieux que la fonction n'a pas encore été pris en charge. Je pensais que je pouvais contourner ce problème en utilisant GetBitmap (), puis accéder au paramètre bmBits. Cependant , cela semble être toujours nul qui a été confirmé lorsque j'ai trouvé le lien suivant: Pourquoi est-ce GetObject renvoie une image bitmap avec bmBits null? .

Ma prochaine tentative était de suivre les conseils dans le lien et utiliser CreateDIBSection () au lieu de CreateCompatibleBitmap (). Cela semble être le bon chemin, et je doit avoir accès aux données que je veux, mais malheureusement je ne peux pas obtenir le DIB pour afficher (code est à la figure 2). Je pense que je suis en train de faire quelque chose de mal dans la création de l'en-tête de la DIB, mais je ne peux pas comprendre ce que mon erreur est.

Si quelqu'un a des suggestions pour un moyen d'accéder aux données dans le bitmap, ou peut voir ce que je fais mal avec le DIB, je serais très reconnaissant de l'aide!

*** FIGURE 1: Code pour créer et afficher une image bitmap

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);

}

*** FIGURE 2: En essayant d'utiliser un DIB au lieu d'un bitmap

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);

}

Créé 13/03/2015 à 14:23
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
0

Je fis donc deux modifications mineures au code DIB, et il affiche l'image correctement maintenant.

Tout d'abord, je l'ai changé la façon dont je passais dans mon pointeur sur le CreateDIBSection ():

void ** ppvBits;

à

LPBYTE pBits;

Et puis je devais changer la façon dont je suis passé que dans CreateDIBSection. J'ai aussi explicitement casté le retour de CreateDIBSection () à un 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);

Je ne l'ai pas eu la chance de voir si je peux accéder aux données d'image, mais je suis passé les premières questions maintenant. Merci à tous ceux qui ont regardé cela, et si les gens savent comment faire la première méthode (bitmap dépendant du périphérique) Je serais intéressé de savoir.

Créé 13/03/2015 à 14:46
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more