Victor Image Processing Library How-to Tips

Print 2-Sided Booklet of Scanned TIFF Images

A typical use of scanner and printer is to combine them as a programmable copy machine. In this example the individual pages of a 51-page document have been scanned and saved as TIFF files named 1.tif, 2.tif, 3.tif and so on. We know the image width, length, and pixel depth to be 1700, 2180, and 8-bit grayscale. To print these on 2 sides of the paper we use a duplex printer and control it with the Victor printimage functions.

The simplified outline of the procedure is

      allocimage(&odd, width, height, 8);       // Allocate space for the odd-numbered page
      allocimage(&even, width, height, 8);      // Allocate space for the even-numbered page
      page = 1; // Start printing on page 1
      while(page <= maxPage ) {
            // Load the next odd and even pages
         loadtif(fn1, &odd);
         loadtif(fn2, &even);
         printimagestartdoc(hPrn, "Booklet"); 
            // Print the first image
         printimagenoeject(hWnd, hPrn, prtmode, &odd, &prtrc, frame, (DLGPROC)DisplayPrtProg);
         EndPage(hPrn); // Advance to the next page
         StartPage(hPrn);
            // Print the second image on the second page
         printimagenoeject(hWnd, hPrn, prtmode, &even, &prtrc, frame, (DLGPROC)DisplayPrtProg);
         printimageenddoc(hPrn, ejectPage);
         page += 2;
         }
         
      freeimage(&odd); // After all the pages are printed release page buffers
      freeimage(&even);
      

Print 2-Sided Booklet of Scanned TIFF Images - the C/C++ Source Code

Requires Victor Image Processing Library v 5.3 or higher.
Add the Victor import library vic32ms.lib (or vic32bc.lib for non-Microsoft compilers) to your project.
void PrinttheBook(HWND hWnd)
{
   int xpos = 0, ypos = 0, frame = 0, rcode;
   HINSTANCE hInst = GetWindowInstance(hWnd);
   HDC hPrn;       // Printer Device Context
   int prtmode = PRTDEFAULT; // Use halftone print mode
   RECT prtrc;
   BOOL ejectPage;   // Eject the page if TRUE
   int width = 1700, height = 2180;
   imgdes odd, even; // Odd and even page buffers
   int rcOdd, rcEven; // Error codes
   int page, maxPage = 51; // Last odd page to print
   TCHAR szBuff[256], fn1[256], fn2[256];
   int nRc, textStx = 180, textSty = 30, textEndx = 1510, textEndy = 2080;
            // Get printer DC
   if((hPrn = GetPrinterDC()) == NULL)
      rcode = PRT_ERR;
   else {
      rcode = NO_ERROR;
      CancelPrt = FALSE; // Clear cancel printing flag
            // Disable main window to prevent closing
      EnableWindow(hWnd, FALSE);
            // Create a "cancel printing" dialog box
      hDlgPrt = CreateDialog(hInst, MAKEINTRESOURCE(IDD_PRTCANCEL), hWnd, (DLGPROC)CancelPrtProc); // See below
            // Set area to print on page
      SetRect(&prtrc, xpos, ypos, xpos + 7999, ypos + 10499);
            // Allocate page buffers
      rcOdd = allocimage(&odd, width, height, 8);
      rcEven = allocimage(&even, width, height, 8);
            // Set doc name for print manager
      GetWindowText(hWnd, szBuff, sizeof(szBuff));
      page = 1; // Start printing on page 1
      while(page <= maxPage && rcode == NO_ERROR && CancelPrt == FALSE ) {
            // Create two filenames
         wsprintf(fn1, (LPTSTR)__TEXT("D:\\scannedpages\\%d.tif"), page);
         wsprintf(fn2, (LPTSTR)__TEXT("D:\\scannedpages\\%d.tif"), page+1);
            // Reset image area to the entire image
         setimagearea(&odd, 0, 0, width-1, height-1);
         setimagearea(&even, 0, 0, width-1, height-1);
            // Load the next odd and even pages
         rcOdd = loadtif(fn1, &odd);
         rcEven = loadtif(fn2, &even);
            // "Zoom" in on the page area to print to eliminate noise around the edges
         setimagearea(&odd, textStx, textSty, textEndx, textEndy);
         setimagearea(&even, textStx, textSty, textEndx, textEndy);
            // Initialize for multi-image printing
         rcode = printimagestartdoc(hPrn, szBuff); 
         if(rcode == NO_ERROR) {
            // Print the first image
            rcode = printimagenoeject(hWnd, hPrn, prtmode, &odd, &prtrc, frame, (DLGPROC)DisplayPrtProg); // See below
            if(CancelPrt == FALSE && rcode == NO_ERROR) {
               EndPage(hPrn); // Tell Windows to print next image on second page
               StartPage(hPrn);
            // Print the second image
               rcode = printimagenoeject(hWnd, hPrn, prtmode, &even,
                  &prtrc, frame, (DLGPROC)DisplayPrtProg);
               }
            // Eject the page if the user didn't abort & no errors
            ejectPage = CancelPrt == FALSE && rcode == NO_ERROR;
            printimageenddoc(hPrn, ejectPage);
            }
         page += 2;
         }
      freeimage(&odd); // Release page buffers
      freeimage(&even);
      EnableWindow(hWnd, TRUE); // Re-enable main window
      DestroyWindow(hDlgPrt);   // Delete "cancel printing" dialog
      hDlgPrt = 0;
      nRc = DeleteDC(hPrn);           // Delete printer DC
      }
   if(rcode != NO_ERROR) 
      MessageBox(hWnd, "Error in printing image", 0, MB_OK);
}
static BOOL CancelPrt;   // Cancel printing flag
static HANDLE hDlgPrt;   // "Cancel printing" dialog box handle
/* Display printing progress number in "cancel printing" dialog box.
   Returns state of cancel printing flag (nonzero if we're to cancel).
*/
int _export WINAPI DisplayPrtProg(int bandno)
{
   MSG msg;
   TCHAR szBuff[64];
            // Display printing progress in cancel printing dialog box
   if(hDlgPrt) {   // If dialog exists...
      wsprintf(szBuff, (LPTSTR)__TEXT("Imaging band number %d"), bandno);
      SetDlgItemText(hDlgPrt, IDC_VAL1, szBuff);
      }
            // Allow other apps to process messages
   while(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
      if(!hDlgPrt || !IsDialogMessage(hDlgPrt, &msg)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
         }
      }
   return(CancelPrt); // Return state of "cancel printing" flag
}
// Dialog proc for "cancel printing" dialog box
int _export WINAPI CancelPrtProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
   (void)hDlg; (void)wParam; (void)lParam;
   if(message == WM_COMMAND) {
      CancelPrt = TRUE; // Cancel printing
      return(TRUE);
      }
   return(FALSE);
}
Victor Image Processing Library

Victor Image Processing Library homepage | Victor Product Summary | more source code




Copyright © 2001 Catenary Systems Inc. All rights reserved. Victor Image Processing Library is a trademark of Catenary Systems.