Thread: Help with Printing BMPs

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    5

    Help with Printing BMPs

    Hi there, Im trying to make a program that takes in a filename of a bmp and then prints out the BMP on a printer selected by the user. Below is the code I have written so far, and when I run it, it asks for the printer name then the filename name , and after i enter these the printer just feeds through 1 sheet of paper and doesnt print anything, I have no idea why, any help would be much appreciated, Thanx in advance.

    Here comes the code :
    Code:
    #include <windows.h>
    #include <windef.h>
    #include <wingdi.h>
    #include <stdio.h>
    #include <winspool.h>
    #include <fstream.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iostream>
    
    using namespace std;
    
    class printer_select;
    
    class imageprint{
            DOCINFO di;
    
            LPBITMAPINFO info;   // Struct for storing the DIB information,
                                             // it will be used by 'StretchDIBits()'
            HBITMAP      hbit;           // Handle to the bitmap to print
            BITMAP       bm;             // Struct used for obtaining information
                                           // about the bitmap (size, color depth...)
            int          nColors;   // store the number of colors the DIB has
            int          sizeinfo;   // Will contain the size of info
            RGBQUAD      rgb[256];       // Used to store the DIB color table
            int          YOUR_BITMAP_ID;
    
            public:
            imageprint(LPCTSTR file_name);
            imageprint(HANDLE fileinstance);
         //   int print(printer_select &printer_ptr);   do this later
            ~imageprint();
    
            };
    
     class printer_select {
          HDC pDC;
          TCHAR Device[50];
    
          public:
          
          printer_select();
          friend int imageprint::print(printer_select &printer_ptr);
          ~printer_select();
          
          };
    
     imageprint::imageprint(LPCTSTR file_name){
    
             nColors  = 0;   //store the number of colors the DIB has
             sizeinfo = 0;   // Will contain the size of info
    
                                  // The following line loads the bitmap from a file
              hbit = (HBITMAP) LoadImage(0,
                                                             file_name,
                                                             IMAGE_BITMAP,
                                                             0,
                                                             0,
                                      LR_CREATEDIBSECTION | LR_LOADFROMFILE);
    
                            // Obtain information about 'hbit' and store it in 'bm'
      
      GetObject(hbit, sizeof(BITMAP), (LPVOID) &bm);
    
       int nColors = (1 << bm.bmBitsPixel);
       if(nColors > 256)
       nColors=0;  // This is when DIB is 24 bit.
    
                         
    // Color table is only needed when the DIB has 256 colors or less.
    
     sizeinfo = sizeof(BITMAPINFO) + (nColors * sizeof(RGBQUAD));
     // This is the size required
    
     info = (LPBITMAPINFO) malloc(sizeinfo);     // Storing info in memory
    
     // Before 'StretchDIBits()' we have to fill some "info" fields.
     // This information was stored in 'bm'.
    
     info->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
     info->bmiHeader.biWidth         = bm.bmWidth;
     info->bmiHeader.biHeight        = bm.bmHeight;
     info->bmiHeader.biPlanes        = 1;
     info->bmiHeader.biBitCount      = bm.bmBitsPixel * bm.bmPlanes;
     info->bmiHeader.biCompression   = BI_RGB;
    info->bmiHeader.biSizeImage     = bm.bmWidthBytes*bm.bmHeight;
    info->bmiHeader.biXPelsPerMeter = 0;
    info->bmiHeader.biYPelsPerMeter = 0;
    info->bmiHeader.biClrUsed       = 0;
    info->bmiHeader.biClrImportant  = 0;
    
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = file_name;
    di.lpszOutput = (LPTSTR) NULL;
    
    if(nColors <= 256)
    {
      HBITMAP hOldBitmap;
      HDC     hMemDC     = CreateCompatibleDC(NULL);    
    
      hOldBitmap = (HBITMAP) SelectObject(hMemDC, hbit); 
      GetDIBColorTable(hMemDC, 0, nColors, rgb); 
    
      // pass this color information to "info"
      for(int iCnt = 0; iCnt < nColors; ++iCnt)
      {
        info->bmiColors[iCnt].rgbRed   = rgb[iCnt].rgbRed;
        info->bmiColors[iCnt].rgbGreen = rgb[iCnt].rgbGreen;
        info->bmiColors[iCnt].rgbBlue  = rgb[iCnt].rgbBlue;
      }
    
      SelectObject(hMemDC, hOldBitmap);
      DeleteDC(hMemDC);
    }
    
    
    }
    
    
    
    
    imageprint::~imageprint(){
    DeleteObject(hbit);
    
    }
    
    
    
    
     int imageprint::print(printer_select &printer_ptr){
      
       //'StretchDIBiting'! 'pDC' is the printer DC
       HDC hdc = CreateCompatibleDC(printer_ptr.pDC); 
    
     StartDoc(printer_ptr.pDC, &di);
     StartPage(printer_ptr.pDC);
    
    StretchDIBits(hdc,
                  0,             //initial_pos_x
                  0,              //initial_pos_y
                  info->bmiHeader.biWidth, //size_x
                  info->bmiHeader.biHeight, //size_y
                  0,
                  0,
                  bm.bmWidth,
                  bm.bmHeight,
                  bm.bmBits,
                  info,
                  DIB_RGB_COLORS,
                  SRCCOPY);
    
      EndPage(printer_ptr.pDC);
      EndDoc(printer_ptr.pDC);
      return 0;
     
     }
    
    printer_select::printer_select(){
    cout<<"enter printername: ";
    cin >> Device;
    pDC = CreateDC("WINSPOOL",Device,NULL,NULL);
    }
    
    
    printer_select::~printer_select(){
    DeleteDC(pDC);
    }
    
    int main(void)
    
    {
    
    printer_select *printer_ptr;
    
    printer_ptr = new printer_select;
    
    TCHAR filename[50];
    cout << "enter filename to print: ";
    cin >> filename;
    
    imageprint first_image(filename);
    
    first_image.print(*printer_ptr);
    }
    Last edited by simtron; 09-08-2005 at 03:35 PM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Does the bitmap load from file?

    >>HDC hdc = CreateCompatibleDC(printer_ptr.pDC);

    Any HDC has a 1x1 mono BMP in it when created. So your SetDIBits will fail.

    try.....
    Select the hbit into hdc,
    catch the returned original bmp,
    copy hdc to printer_ptr.pDC with BitBlt() or StretchBlt(),
    Select the original bmp back,
    Delete the hdc.



    I do this by BitBlt()'ing or StretchBlt()'ing the image to the printers HDC (rather than setting the printers HDC bits).

    Keep the bitmap in the compatible DC you create and clean both the HDC and BMP up after you have printed them.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    May 2005
    Posts
    5

    Smile Sorted . got image to print out on my printer

    Thanks novacain.
    I realised the error in my code. This line
    Code:
    StretchDIBits(hdc,
    should be like this
    Code:
    StretchDIBits(printer_ptr.pDC,
    I also rewrote the program using the methods you suggested and they also worked. Thanks.
    Now im gonna go improve and trim some of the fat off my code. Eventually I want to expand the code to be able to print any image format like jpg, gif etc from file. Anyone got any suggestions for the best way to do this?

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    GDI+ supports most image types.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    Registered User
    Join Date
    May 2005
    Posts
    5
    Thanks again novacain, Ive been reading up on this gdi+ and it makes things a whole lot easier, reckon I can do the same as above in about 10 lines of code. And I thought I'd have to decode the jpeg files manually. lol

  6. #6
    Registered User
    Join Date
    May 2005
    Posts
    5

    Hit A Brick Wall

    Hi Again , I've recoded the program to use gdi+, but i get some weird behaviour when i print out the image. Im using the drawimage method of the graphics class to send it to the printer, but when it prints out it prints out an image thats zoomed in (about 300%) to 1 of the corners. Heres the code for the printing part:
    Code:
    image_ptr->GetBounds(&boundsRect, &unit);
    
    Rect destRect(GetDeviceCaps(pDC,PHYSICALOFFSETX),
                           GetDeviceCaps(pDC,PHYSICALOFFSETY), 
                           (int)GetDeviceCaps(pDC,HORZRES),
                           (int)GetDeviceCaps(pDC,VERTRES));
    
    graphics->DrawImage(image_ptr,
                         destRect,           // X:40 Y:38 Width:2400 Height:3319
                        (int)boundsRect.X, //0
                        (int)boundsRect.Y,  //0
                        image_ptr->GetWidth(),  //3681
                        image_ptr->GetHeight(),  //5140
                        UnitPixel,
                        NULL,NULL,NULL
                      );
    AFAIK the drawImage function works like the stretchdibits function and should scale the image to fit the destRect. So I cant see why it is printing out a zoomed in image. BTW the numbers in comments are the vlues obtained during debugging for the image im trying to print and for the printer im trying to use.

    Id be very grateful if anyone can point out where Im going wrong. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C# Printing Problem
    By silverlight001 in forum C# Programming
    Replies: 0
    Last Post: 03-23-2009, 01:13 AM
  2. generic printing preferences dialog box
    By stanlvw in forum Windows Programming
    Replies: 8
    Last Post: 06-27-2008, 02:20 AM
  3. printing data to a file
    By coralreef in forum C Programming
    Replies: 3
    Last Post: 11-02-2006, 08:10 PM
  4. need help relating printing?
    By omarlodhi in forum Linux Programming
    Replies: 0
    Last Post: 03-03-2006, 04:46 AM
  5. Printing
    By Dual-Catfish in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 05-25-2002, 08:10 PM