且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我想在没有任何gui的情况下从类库项目中打印图像。

更新时间:2022-12-15 13:57:32

LoadImage 函数返回一个颜色的位图映射到显示设备的颜色。这不能用于选择打印机兼容设备上下文,因为颜色深度通常不相同。在加载图像时使用 LR_CREATEDIBSECTION 标志以获取设备独立位图。



您还应该检查是否打印机通过调用 GetDeviceCaps 并检查 RASTERCAPS RC_BITBLT $ c来支持栅格操作$ c>标志。如果打印机不支持光栅操作, BitBlt 将失败。
The LoadImage function returns a bitmap with colors mapped to those of the display device. This can't be used to be selected into a printer compatible device context because the color depth is usually not the same. Use the LR_CREATEDIBSECTION flag when loading the image to get a device independant bitmap.

You should also check if your printer supports raster operations by calling GetDeviceCaps and checking for the RASTERCAPS and RC_BITBLT flags. If the printer does not support raster operations, BitBlt will fail.


如上所述,LoadImage加载图像以备在屏幕上输出。您已经提供了替代方案,或者使用GDI +加载图像。使用GDI +的优点是不仅可以创建DIB,还可以加载包括png,jpg和gif在内的格式。



如果你已经初始化了GDI +,以下功能将加载图像以备屏幕或打印。



As mentioned, LoadImage loads an image ready for output on a screen. You have the alternative already given, or to use GDI+ to load the image. The advantage of using GDI+ is that not only is a DIB created, but you can also load formats including png, jpg and gif.

Provided you have already intialized GDI+, the following function will load an image ready for screen or print.

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
HBITMAP mLoadImageFile(wchar_t *filename)
{
    HBITMAP result = NULL;
    Bitmap bitmap(filename, false);
    bitmap.GetHBITMAP(0, &result);
    return result;
}







如果未使用GDI +,您可以使用dib部分标记LoadImage。

以下代码创建1页pdf,加载已从gif转换为bmp的CP徽标的副本。



只需:

(a)更改 drawPage $ c $中加载图像的名称c>功能

(b)更改 main 第一行中打印机的名称



注意:链接gdi32和winspool库。






Failing the use of GDI+, you can use the dib section flag with LoadImage.
The following code creates a 1 page pdf, loading a copy of the CP logo that's been converted from gif to bmp.

Just:
(a) change the name of the loaded image in the drawPage function
(b) change the name of the printer in the 1st line of main

Note: Link against the gdi32 and winspool libraries.

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>


void drawPage(HDC hdc)
{
    HBITMAP logo = (HBITMAP)LoadImage(NULL, "logo.bmp", IMAGE_BITMAP, 0,0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);

    int pageWidth, pageHeight;
    pageWidth = GetDeviceCaps( hdc, HORZRES ),
    pageHeight = GetDeviceCaps( hdc, VERTRES );
    int dpiX, dpiY;

    dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
    dpiY = GetDeviceCaps(hdc, LOGPIXELSY);

    double dpiMmX, dpiMmY;

    dpiMmX = dpiX / 25.4;
    dpiMmY = dpiY / 25.4;

    HBRUSH redBrush = CreateSolidBrush( RGB(255,0,0) );
    RECT pageRect = {0,0,pageWidth,pageHeight};

    int borderWidth = dpiMmX * 10;
    int borderHeight = dpiMmY * 10;

    RECT borderRect = {borderWidth, borderHeight, pageWidth-1-borderWidth, pageHeight-1-borderHeight};

    FrameRect(hdc, &pageRect, redBrush);
    int i;
    for (i=0; i<5; i++)
    {
        FrameRect(hdc, &borderRect, redBrush);
        InflateRect(&borderRect, -1, -1);
    }

    HDC memDC = CreateCompatibleDC(hdc);
    HBITMAP old = (HBITMAP)SelectObject(memDC, logo);
    StretchBlt(hdc, 100,100, 1000,540, memDC, 0,0, 250,125, SRCCOPY);
    SelectObject(memDC, old);
    DeleteObject(logo);
    DeleteDC(memDC);

    DeleteObject(redBrush);
}


void testPrint(char *szPrinterName)
{
    DOCINFO diDocInfo = {0};
    diDocInfo.cbSize = sizeof( DOCINFO );
    diDocInfo.lpszDocName = "printTest";

    HANDLE printerHandle;
    if (OpenPrinter(szPrinterName, &printerHandle, NULL) != 0)
    {
        HDC pDC2 = CreateDC("", szPrinterName, NULL, NULL);

        if( StartDoc( pDC2, &diDocInfo ) > 0 )
        {
            if( StartPage( pDC2 ) > 0 )
            {
                drawPage(pDC2);
                EndPage(pDC2);
            }
            EndDoc( pDC2 );
        }
        ClosePrinter(printerHandle);
    }
}

int main()
{
    testPrint("CutePDF Writer");
    return 0;
}







编辑:添加了MFC代码






MFC code added

// CdcTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "CdcTest.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// The one and only application object

CWinApp theApp;

using namespace std;

void drawPage(HDC hdc)
{
    HBITMAP logo = (HBITMAP)LoadImage(NULL, L"c:/logo.bmp", IMAGE_BITMAP, 0,0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);

    int pageWidth, pageHeight;
    pageWidth = GetDeviceCaps( hdc, HORZRES ),
    pageHeight = GetDeviceCaps( hdc, VERTRES );
    int dpiX, dpiY;

    dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
    dpiY = GetDeviceCaps(hdc, LOGPIXELSY);

    double dpiMmX, dpiMmY;

    dpiMmX = dpiX / 25.4;
    dpiMmY = dpiY / 25.4;

    HBRUSH redBrush = CreateSolidBrush( RGB(255,0,0) );
    RECT pageRect = {0,0,pageWidth,pageHeight};

    int borderWidth = dpiMmX * 10;
    int borderHeight = dpiMmY * 10;

    RECT borderRect = {borderWidth, borderHeight, pageWidth-1-borderWidth, pageHeight-1-borderHeight};

    FrameRect(hdc, &pageRect, redBrush);
    int i;
    for (i=0; i<5; i++)
    {
        FrameRect(hdc, &borderRect, redBrush);
        InflateRect(&borderRect, -1, -1);
    }

    HDC memDC = CreateCompatibleDC(hdc);
    HBITMAP old = (HBITMAP)SelectObject(memDC, logo);
    StretchBlt(hdc, 100,100, 1000,540, memDC, 0,0, 250,125, SRCCOPY);
    SelectObject(memDC, old);
    DeleteObject(logo);
    DeleteDC(memDC);

    DeleteObject(redBrush);
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	HMODULE hModule = ::GetModuleHandle(NULL);

	if (hModule != NULL)
	{
		// initialize MFC and print and error on failure
		if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
		{
			// TODO: change error code to suit your needs
			_tprintf(_T("Fatal Error: MFC initialization failed\n"));
			nRetCode = 1;
		}
		else
		{
			// TODO: code your application's behavior here.
			CDC memDC;
			memDC.CreateDCW(NULL, L"CutePDF Writer", NULL, NULL);

			DOCINFO diDocInfo = {0};
			diDocInfo.cbSize = sizeof( DOCINFO );
			diDocInfo.lpszDocName = L"printTest";

			if( StartDoc( memDC.GetSafeHdc(), &diDocInfo ) > 0 )
			{
				if( StartPage( memDC.GetSafeHdc() ) > 0 )
				{
					drawPage(memDC.GetSafeHdc());
					EndPage(memDC.GetSafeHdc());
				}
				EndDoc( memDC.GetSafeHdc() );
			}

		}
	}
	else
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
		nRetCode = 1;
	}

	return nRetCode;
}