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);
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 homepage | Victor Product Summary | more source code