打印到TIFF, 图片打印机
源码: http://download.csdn.net/detail/kingmax54212008/9920964
如还有问题,请关注博主的其它打印驱动开发相关资料。或联系我的邮箱: kingmax5421@126.com
介绍
我个人不是PDF的粉丝。对我来说,它不是“开放”,它是大的,通常你不能编辑它后。我们经常在这些PDF文件中收到文件,如工资单和纸币。对于我的管理,我最近做了一些努力,从纸到电脑。我想使用“开放标准”,如TIFF和HTML。PDF不合适。所以我需要一种将PDF转换成TIFF的方法。这就是这个代码。
背景
我搜索了一些时间找到一些代码或工具将PDF转换为TIFF。不幸的是,我只能找到商业产品。而且我不知道如果我买一个,那就做我想要的。所以我寻找办法自己去做。
PDF和TIFF之间有很大的区别。PDF文档被“渲染”,而TIFF只是一堆像素。这意味着如果您在PDF查看器中放大页面,它将保持清晰。另一方面,TIFF图像的分辨率有限。当然,您可以在PDF文档上按AltPrintScreen,但是您的设备(显示器)的大部分不会得到更好的分辨率(像素数)。我没有找到一种方法让PDF查看器在设备上下文中比物理屏幕的设备上下文更大。幸运的是,微软提供了一个Printer驱动程序示例,更幸运的是,由于有一段时间您可以下载包含示例的Windows驱动程序工具包。虽然代码在用户模式下运行,但它是驱动程序。
使用打印机驱动程序,像素数量可能非常高。至少足以在正常页面上进行打印。此外,通过更改应用程序中的打印机属性,可以更改DPI,尺寸和颜色数量。更重要的是:只要应用程序可以打印,现在就可以将任何东西转换成TIFF。
入门
Microsoft示例是一个工作驱动程序。它将页面打印到一个位图(.BMP)。使用TIFF的一个原因是一个文件可以包含多个页面。因此,代码必须添加到样本中以分别写入每个页面,并将其写入TIFF而不是BMP。
要开始使用,您必须获得Windows驱动程序工具包。按照以下步骤:
- 下载Windows驱动程序工具包。
- 它是一个ISO,所以你必须在CD刻录,或使用一些实用工具来安装图像。
- 安装WDK。确保选择了完整开发环境。
- 我建议将样本复制到您的代码的其余部分所在的地方(并且您定期备份,对吗?)。将<WinDDK-dir> \ src \print\ oemdll \ bitmap复制到<your-dir> \ Bitmap_Driver(确保路径和名称中没有空格)!
- 做一个目录
Bitmap_Driver
,例如“Pack
”。这将是将驱动程序分发到CD / DVD / USB / HD / FD / ...的目录 - 将一些WinDDK文件从[...] src \print\ oemdll复制到新目录[...] \ Bitmap_Driver \ Pack:
- bitmap.gpd
- bitmap.inf
- bitmap.ini
- 在makefile.inc中,将第一行更改为“INSTALLDIR =。\ Pack \ bitmap”(不带引号)
- 现在您可以第一次构建示例。
构建驱动程序
正确的构建环境取决于计算机要使用它的位置。在开始菜单中,选择Windows驱动程序套件,WDK 7600。[...],Windows <您选择>,x <您选择>自由构建环境。这将打开一个具有正确设置的cmd框。在此框中,切换到您的Bitmap_Driver目录。然后键入“build”(不带引号)。您的驱动程序(bitmap.dll)将在Pack \ bitmap \ <架构>目录中。此路径在驱动程序文件中定义:bitmap.inf。
使用代码
现在是添加代码以使其写入多页TIFF的时候了。需要更改以下文件:bitmap.h,intrface.cpp,ddihook.cpp,precomp.h和源。
简而言之,这是打印时会发生什么:
COemUni2::EnablePDEV
- 初始化所有的东西OEMStartPage
- 当新页面启动时调用的钩子OEMSendPage
- 通常不会被调用。我们不使用它COemUni2::ImageProcessing
- 每个数据块之后COemUni2::FilterGraphics
- 我们不使用OEMEndDoc
- 最后一页后。这里我们将数据发送到打印子系统COemUni2::DisablePDEV
每一页都印在一个或多个部分。渲染的一部分之后,该方法在intrface.cpp被调用。该方法增加一个缓冲区并添加新的图形数据。该示例将挂起事件。在这个挂钩功能中,缓冲区被给予“打印子系统”,实际上它将写入您点击打印时指定的文件。COemUni2::ImageProcessing
OEMEndDoc
因为我们要写一个Multipage TIFF,所以我们需要收到一个新页面开始的通知。因此,我们要勾画OEMStartPage
。你可能会期望这样OEMSendPage
会更有意义,但事实证明它通常不会被调用。
static const> DRVFN s_aOemHookFuncs[] = {
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
{INDEX_DrvStartPage, (PFN) OEMStartPage},
{INDEX_DrvSendPage, (PFN) OEMSendPage}
};
当OEMStartPage
被调用时,我们正在开始一个新的页面。在这一刻,我们必须写上一页。
//--- Write the previous page - if exists ---
if (pOemPDEV->pBufStart) {if (SaveFrame( pOemPDEV, pDevObj, false))pOemPDEV->m_iframe+=1;}
然后启动一个新的:
//--- New page ---
//Initializing private oempdev stuff
pOemPDEV->bHeadersFilled = FALSE;
pOemPDEV->bColorTable = FALSE;
pOemPDEV->cbHeaderOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pOemPDEV->bmInfoHeader.biHeight = 0;
pOemPDEV->bmInfoHeader.biSizeImage = 0;
pOemPDEV->pBufStart = NULL;
pOemPDEV->dwBufSize = 0;
SaveFrame
是将一个页面写入缓冲区的新功能。这里我们要把一些代码写入一个TIFF文件中的缓冲区。这个文件实际上是一个内存流,因为在最后(OEMEndDoc
)我们必须将数据直接传递给假脱机程序。
![](https://www.codeproject.com/images/arrow-up-16.png)
/*******************************************************\
*
* Save Frame
*
\*******************************************************/
BOOL SaveFrame(POEMPDEV pOemPDEV, PDEVOBJ pdevobj, BOOL fClose) {INT cScans;Gdiplus::Bitmap* pbmp = NULL; //second+ frames: local bitmaplog( L"SaveFrame");//--- Number of scanlines ---cScans = pOemPDEV->bmInfoHeader.biHeight;//--- Flip the biHeight member so that it denotes top-down bitmap ---pOemPDEV->bmInfoHeader.biHeight = cScans * -1;BITMAPINFO* pbmpinf = (BITMAPINFO*) LocalAlloc( LPTR, sizeof(BITMAPINFOHEADER) + (pOemPDEV->cPalColors * sizeof(ULONG)));CopyMemory( &pbmpinf->bmiHeader, &pOemPDEV->bmInfoHeader, sizeof(BITMAPINFOHEADER));if (pOemPDEV->bColorTable) {CopyMemory( &pbmpinf->bmiColors, pOemPDEV->prgbq, pOemPDEV->cPalColors*sizeof(RGBQUAD));LocalFree(pOemPDEV->prgbq);}Gdiplus::Status sstat;log(L"init Gdiplus::Bitmap");if (!pOemPDEV->m_pbmp) //Make Bitmap for the first timepOemPDEV->m_pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);else //Second time: local bitmappbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);if ((pOemPDEV->m_pbmp) || (pbmp)) {//--- Encoder Parameters ---Gdiplus::EncoderParameters* pEncoderParameters = (Gdiplus::EncoderParameters*)LocalAlloc( LPTR, sizeof(Gdiplus::EncoderParameters) + 2*sizeof(Gdiplus::EncoderParameter));ULONG parameterValue0;ULONG parameterValue1;//An EncoderParameters object has an//array of EncoderParameter objects.pEncoderParameters->Count = 2;pEncoderParameters->Parameter[0].Guid = Gdiplus::EncoderCompression;pEncoderParameters->Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;pEncoderParameters->Parameter[0].NumberOfValues = 1;pEncoderParameters->Parameter[0].Value = ¶meterValue0;pEncoderParameters->Parameter[1].Guid = Gdiplus::EncoderSaveFlag;pEncoderParameters->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;pEncoderParameters->Parameter[1].NumberOfValues = 1;pEncoderParameters->Parameter[1].Value = ¶meterValue1;//Black n White: CCITT4, else LZWif (pOemPDEV->bmInfoHeader.biBitCount == 1)parameterValue0 = Gdiplus::EncoderValueCompressionCCITT4;elseparameterValue0 = Gdiplus::EncoderValueCompressionLZW;CLSID clsid;GetEncoderClsid(L"image/tiff", &clsid);log(L"Save (frame: %u)", pOemPDEV->m_iframe);if (pOemPDEV->m_iframe == 0) { //First frameparameterValue1 = Gdiplus::EncoderValueMultiFrame;pOemPDEV->m_pbmp->SetResolution( pdevobj->pPublicDM->dmPrintQuality, pdevobj->pPublicDM->dmYResolution);sstat = pOemPDEV->m_pbmp->Save( pOemPDEV->m_pstm, &clsid, pEncoderParameters);}else { //Second+ frameparameterValue1 = Gdiplus::EncoderValueFrameDimensionPage;//TODO: Necessary?pbmp->SetResolution( pdevobj->pPublicDM->dmPrintQuality, pdevobj->pPublicDM->dmYResolution);sstat = pOemPDEV->m_pbmp->SaveAdd( pbmp, pEncoderParameters);if (pbmp)delete [] pbmp;}if (sstat != Gdiplus::Ok) log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);if (fClose) {//Finishing:parameterValue1 = Gdiplus::EncoderValueFlush;sstat = pOemPDEV->m_pbmp->SaveAdd(pEncoderParameters);}LocalFree( pEncoderParameters);}elselog(L"Couldn\'t make Gdiplus::Bitmap");LocalFree( pbmpinf);return true;}
正如你所看到的,我们使用Gdiplus做这个工作。为什么我们在第一帧中使用成员变量作为位图,然后为以下帧使用局部变量?当我们要添加一个页面到第一个,我们使用一个方法在初始位图,所以我们必须重用那个。
要完整地关闭文件,在end(OEMEndDoc
)中,EncoderValueFlush
通过设置参数来指示函数的写入fClose
。
安装打印呃
现在让我们安装打印机,然后尝试一下。
- 添加本地打印呃
- 使用现有端口:FILE:(打印到文件)
- 有磁盘...
- 浏览到<your-dir> \ Bitmap_Driver \ Pack,然后选择bitmap.inf
- 如果这不是第一次:更换当前驱动程序
- 接下来,下一步,完成
现在打印一些新的打印呃。
如果你不能使它工作
记录
正如你可能已经注意到的,在某些点上,一行显示如下:
log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);
因为它是一个驱动程序,你不能直接写入屏幕。另外,调试并不那么容易。这就是为什么我添加了一个函数来写消息使用OutputDebugStringW
。您可能知道,您必须做一些额外的工作才能使用Windows 7查看邮件:
- 使用RegEdit:导航到HKLM \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Debug打印过滤器
- 将DEFAULT的值更改为0xf(
REG_DWORD
) - 重启
- 您可以使用
DbgView
(以前的Sysinternals)查看消息,并选择“Capture Global Win32”
现在可以在代码中添加日志记录。
重新安装新版本后无更改
Windows从驱动程序缓存中选出相同的旧驱动程序。要安装新的,请更改bitmap.inf中的驱动程序版本,然后重新安装。现在新的驱动程序将被安装。
错误0x000003eb
如果您尝试安装驱动程序,将显示此错误。在这种情况下,文件bitmap.gpd可能会有错误。如果您更改了它,请尝试将其替换为原件。
兴趣点
由于Gdiplus用于保存文件,因此很容易将驱动程序保存为JPEG,GIF或其他类型的文件。事实上,它与更改行一样简单但是:其他格式不支持一个文件中的多个页面。所以,如果您需要另一种文件格式,最好从原始样本开始,然后添加代码以使用Gdiplus(in)保存文件。另外,检查源的依赖关系:“gdiplus.lib”和precomp.h:“gdiplus.h”GetEncoderClsid(L"image/tiff", &clsid);
OEMEndDoc(...)
介绍
我个人不是PDF的粉丝。对我来说,它不是“开放”,它是大的,通常你不能编辑它后。我们经常在这些PDF文件中收到文件,如工资单和纸币。对于我的管理,我最近做了一些努力,从纸到电脑。我想使用“开放标准”,如TIFF和HTML。PDF不合适。所以我需要一种将PDF转换成TIFF的方法。这就是这个代码。
背景
我搜索了一些时间找到一些代码或工具将PDF转换为TIFF。不幸的是,我只能找到商业产品。而且我不知道如果我买一个,那就做我想要的。所以我寻找办法自己去做。
PDF和TIFF之间有很大的区别。PDF文档被“渲染”,而TIFF只是一堆像素。这意味着如果您在PDF查看器中放大页面,它将保持清晰。另一方面,TIFF图像的分辨率有限。当然,您可以在PDF文档上按AltPrintScreen,但是您的设备(显示器)的大部分不会得到更好的分辨率(像素数)。我没有找到一种方法让PDF查看器在设备上下文中比物理屏幕的设备上下文更大。幸运的是,微软提供了一个Printer驱动程序示例,更幸运的是,由于有一段时间您可以下载包含示例的Windows驱动程序工具包。虽然代码在用户模式下运行,但它是驱动程序。
使用打印机驱动程序,像素数量可能非常高。至少足以在正常页面上进行打印。此外,通过更改应用程序中的打印机属性,可以更改DPI,尺寸和颜色数量。更重要的是:只要应用程序可以打印,现在就可以将任何东西转换成TIFF。
入门
Microsoft示例是一个工作驱动程序。它将页面打印到一个位图(.BMP)。使用TIFF的一个原因是一个文件可以包含多个页面。因此,代码必须添加到样本中以分别写入每个页面,并将其写入TIFF而不是BMP。
要开始使用,您必须获得Windows驱动程序工具包。按照以下步骤:
- 下载Windows驱动程序工具包。
- 它是一个ISO,所以你必须在CD刻录,或使用一些实用工具来安装图像。
- 安装WDK。确保选择了完整开发环境。
- 我建议将样本复制到您的代码的其余部分所在的地方(并且您定期备份,对吗?)。将<WinDDK-dir> \ src \print\ oemdll \ bitmap复制到<your-dir> \ Bitmap_Driver(确保路径和名称中没有空格)!
- 做一个目录
Bitmap_Driver
,例如“Pack
”。这将是将驱动程序分发到CD / DVD / USB / HD / FD / ...的目录 - 将一些WinDDK文件从[...] src \print\ oemdll复制到新目录[...] \ Bitmap_Driver \ Pack:
- bitmap.gpd
- bitmap.inf
- bitmap.ini
- 在makefile.inc中,将第一行更改为“INSTALLDIR =。\ Pack \ bitmap”(不带引号)
- 现在您可以第一次构建示例。
构建驱动程序
正确的构建环境取决于计算机要使用它的位置。在开始菜单中,选择Windows驱动程序套件,WDK 7600。[...],Windows <您选择>,x <您选择>自由构建环境。这将打开一个具有正确设置的cmd框。在此框中,切换到您的Bitmap_Driver目录。然后键入“build”(不带引号)。您的驱动程序(bitmap.dll)将在Pack \ bitmap \ <架构>目录中。此路径在驱动程序文件中定义:bitmap.inf。
使用代码
现在是添加代码以使其写入多页TIFF的时候了。需要更改以下文件:bitmap.h,intrface.cpp,ddihook.cpp,precomp.h和源。
简而言之,这是打印时会发生什么:
COemUni2::EnablePDEV
- 初始化所有的东西OEMStartPage
- 当新页面启动时调用的钩子OEMSendPage
- 通常不会被调用。我们不使用它COemUni2::ImageProcessing
- 每个数据块之后COemUni2::FilterGraphics
- 我们不使用OEMEndDoc
- 最后一页后。这里我们将数据发送到打印子系统COemUni2::DisablePDEV
每一页都印在一个或多个部分。渲染的一部分之后,该方法在intrface.cpp被调用。该方法增加一个缓冲区并添加新的图形数据。该示例将挂起事件。在这个挂钩功能中,缓冲区被给予“打印子系统”,实际上它将写入您点击打印时指定的文件。COemUni2::ImageProcessing
OEMEndDoc
因为我们要写一个Multipage TIFF,所以我们需要收到一个新页面开始的通知。因此,我们要勾画OEMStartPage
。你可能会期望这样OEMSendPage
会更有意义,但事实证明它通常不会被调用。
static const> DRVFN s_aOemHookFuncs[] = {
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
{INDEX_DrvStartPage, (PFN) OEMStartPage},
{INDEX_DrvSendPage, (PFN) OEMSendPage}
};
当OEMStartPage
被调用时,我们正在开始一个新的页面。在这一刻,我们必须写上一页。
//--- Write the previous page - if exists ---
if (pOemPDEV->pBufStart) {if (SaveFrame( pOemPDEV, pDevObj, false))pOemPDEV->m_iframe+=1;}
然后启动一个新的:
//--- New page ---
//Initializing private oempdev stuff
pOemPDEV->bHeadersFilled = FALSE;
pOemPDEV->bColorTable = FALSE;
pOemPDEV->cbHeaderOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pOemPDEV->bmInfoHeader.biHeight = 0;
pOemPDEV->bmInfoHeader.biSizeImage = 0;
pOemPDEV->pBufStart = NULL;
pOemPDEV->dwBufSize = 0;
SaveFrame
是将一个页面写入缓冲区的新功能。这里我们要把一些代码写入一个TIFF文件中的缓冲区。这个文件实际上是一个内存流,因为在最后(OEMEndDoc
)我们必须将数据直接传递给假脱机程序。
![](https://www.codeproject.com/images/arrow-up-16.png)
/*******************************************************\
*
* Save Frame
*
\*******************************************************/
BOOL SaveFrame(POEMPDEV pOemPDEV, PDEVOBJ pdevobj, BOOL fClose) {INT cScans;Gdiplus::Bitmap* pbmp = NULL; //second+ frames: local bitmaplog( L"SaveFrame");//--- Number of scanlines ---cScans = pOemPDEV->bmInfoHeader.biHeight;//--- Flip the biHeight member so that it denotes top-down bitmap ---pOemPDEV->bmInfoHeader.biHeight = cScans * -1;BITMAPINFO* pbmpinf = (BITMAPINFO*) LocalAlloc( LPTR, sizeof(BITMAPINFOHEADER) + (pOemPDEV->cPalColors * sizeof(ULONG)));CopyMemory( &pbmpinf->bmiHeader, &pOemPDEV->bmInfoHeader, sizeof(BITMAPINFOHEADER));if (pOemPDEV->bColorTable) {CopyMemory( &pbmpinf->bmiColors, pOemPDEV->prgbq, pOemPDEV->cPalColors*sizeof(RGBQUAD));LocalFree(pOemPDEV->prgbq);}Gdiplus::Status sstat;log(L"init Gdiplus::Bitmap");if (!pOemPDEV->m_pbmp) //Make Bitmap for the first timepOemPDEV->m_pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);else //Second time: local bitmappbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);if ((pOemPDEV->m_pbmp) || (pbmp)) {//--- Encoder Parameters ---Gdiplus::EncoderParameters* pEncoderParameters = (Gdiplus::EncoderParameters*)LocalAlloc( LPTR, sizeof(Gdiplus::EncoderParameters) + 2*sizeof(Gdiplus::EncoderParameter));ULONG parameterValue0;ULONG parameterValue1;//An EncoderParameters object has an//array of EncoderParameter objects.pEncoderParameters->Count = 2;pEncoderParameters->Parameter[0].Guid = Gdiplus::EncoderCompression;pEncoderParameters->Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong;pEncoderParameters->Parameter[0].NumberOfValues = 1;pEncoderParameters->Parameter[0].Value = ¶meterValue0;pEncoderParameters->Parameter[1].Guid = Gdiplus::EncoderSaveFlag;pEncoderParameters->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong;pEncoderParameters->Parameter[1].NumberOfValues = 1;pEncoderParameters->Parameter[1].Value = ¶meterValue1;//Black n White: CCITT4, else LZWif (pOemPDEV->bmInfoHeader.biBitCount == 1)parameterValue0 = Gdiplus::EncoderValueCompressionCCITT4;elseparameterValue0 = Gdiplus::EncoderValueCompressionLZW;CLSID clsid;GetEncoderClsid(L"image/tiff", &clsid);log(L"Save (frame: %u)", pOemPDEV->m_iframe);if (pOemPDEV->m_iframe == 0) { //First frameparameterValue1 = Gdiplus::EncoderValueMultiFrame;pOemPDEV->m_pbmp->SetResolution( pdevobj->pPublicDM->dmPrintQuality, pdevobj->pPublicDM->dmYResolution);sstat = pOemPDEV->m_pbmp->Save( pOemPDEV->m_pstm, &clsid, pEncoderParameters);}else { //Second+ frameparameterValue1 = Gdiplus::EncoderValueFrameDimensionPage;//TODO: Necessary?pbmp->SetResolution( pdevobj->pPublicDM->dmPrintQuality, pdevobj->pPublicDM->dmYResolution);sstat = pOemPDEV->m_pbmp->SaveAdd( pbmp, pEncoderParameters);if (pbmp)delete [] pbmp;}if (sstat != Gdiplus::Ok) log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);if (fClose) {//Finishing:parameterValue1 = Gdiplus::EncoderValueFlush;sstat = pOemPDEV->m_pbmp->SaveAdd(pEncoderParameters);}LocalFree( pEncoderParameters);}elselog(L"Couldn\'t make Gdiplus::Bitmap");LocalFree( pbmpinf);return true;}
正如你所看到的,我们使用Gdiplus做这个工作。为什么我们在第一帧中使用成员变量作为位图,然后为以下帧使用局部变量?当我们要添加一个页面到第一个,我们使用一个方法在初始位图,所以我们必须重用那个。
要完整地关闭文件,在end(OEMEndDoc
)中,EncoderValueFlush
通过设置参数来指示函数的写入fClose
。
安装打印呃
现在让我们安装打印机,然后尝试一下。
- 添加本地打印呃
- 使用现有端口:FILE:(打印到文件)
- 有磁盘...
- 浏览到<your-dir> \ Bitmap_Driver \ Pack,然后选择bitmap.inf
- 如果这不是第一次:更换当前驱动程序
- 接下来,下一步,完成
现在打印一些新的打印呃。
如果你不能使它工作
记录
正如你可能已经注意到的,在某些点上,一行显示如下:
log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);
因为它是一个驱动程序,你不能直接写入屏幕。另外,调试并不那么容易。这就是为什么我添加了一个函数来写消息使用OutputDebugStringW
。您可能知道,您必须做一些额外的工作才能使用Windows 7查看邮件:
- 使用RegEdit:导航到HKLM \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Debug打印过滤器
- 将DEFAULT的值更改为0xf(
REG_DWORD
) - 重启
- 您可以使用
DbgView
(以前的Sysinternals)查看消息,并选择“Capture Global Win32”
现在可以在代码中添加日志记录。
重新安装新版本后无更改
Windows从驱动程序缓存中选出相同的旧驱动程序。要安装新的,请更改bitmap.inf中的驱动程序版本,然后重新安装。现在新的驱动程序将被安装。
错误0x000003eb
如果您尝试安装驱动程序,将显示此错误。在这种情况下,文件bitmap.gpd可能会有错误。如果您更改了它,请尝试将其替换为原件。
兴趣点
由于Gdiplus用于保存文件,因此很容易将驱动程序保存为JPEG,GIF或其他类型的文件。事实上,它与更改行一样简单但是:其他格式不支持一个文件中的多个页面。所以,如果您需要另一种文件格式,最好从原始样本开始,然后添加代码以使用Gdiplus(in)保存文件。另外,检查源的依赖关系:“gdiplus.lib”和precomp.h:“gdiplus.h”GetEncoderClsid(L"image/tiff", &clsid);
OEMEndDoc(...)
打印到TIFF, 图片打印机相关推荐
- C#调用系统默认打印机打印文字和图片
本方法适用于有打印驱动的打印机打印.直接用电脑默认打印机进行打印文字和图片. 首先安装打印机驱动,然后在设备和打印机中将要用的打印机设为默认打印机,然后调用该方法即可 Pulic Void Print ...
- linux下打印图片不显示出来的,为什么打印机打印不了图片_解决打印机打印不了图片的方法-系统城...
在办公室上班的都会接触到打印机,大家在使用打印机会碰到打印不出图片的情况,为什么会这样呢?出现这种情况排除打印机驱动外,一般是由于打印机的设置不当造成的.针对此疑问,小编教你解决打印机打印不了图片的方 ...
- Unity调用打印机打印文本或者图片
Unity调用打印机打印文本或者图片 通过windows命令行使用记事本打印文本 private void PrintTxt(){//picPath=Application.streamingAsse ...
- java word转图片tiff_Word 2010中将文档保存为TIFF图片的方法
在Word 2003以前的Word版本中,用户可以通过"Microsoft Office Document Image Writer"打印机将Word文档保存为TIFF图片.但是在 ...
- Win7图片查看器打印不了图片怎么办
当我们想浏览电脑中的图片文件时,可以选择系统自带的图片查看器或者第三方看图工具打开,但是有些win7用户发现自己想通过windows图片查看器打印图片却没有反应,Win7图片查看器打印不了图片怎么办? ...
- PhotoShop彩色图片打印机只有四中颜色操作步骤:
打印彩色图片打印机只有四中颜色操作步骤: 1.图片调成灰度模式: 2.建立色调分离模版选择4: 3.图片调整为CMYK模式: 4.调整魔棒工具: 5.用魔棒工具勾选第一个色调,建立新的图层-按住alt ...
- 打印机打印的时候会打印计算机用户,共享打印机无法打印怎么办 共享打印机无法打印解决方法【图文】...
用户在使用电脑时可能会经常碰到 共享 打印机 和电脑连接不上的情况,表现为主机启动后 打印机 不联机,或者在打印文件时主机死锁或者打印机无响应.大多数情况下,这些并不是打印机发生了硬件故障,那么 共享 ...
- 关于图片的一些说法 批量打印 批量制造图片
-------批量打印 1.如何批量处理打印图片及相片等 要求安装"ACDsee"看图软件 2.全能美图看看!看照片还能批量打印照片 要求安装"美图看看" ...
- 计算机打印驱动怎么安装,打印机安装步骤,教您电脑怎么安装打印机驱动
工作和生活中很多时候都会用到打印机,可以用打印机来打印文件,图片等等,是办公设备中不可缺少的一种,但是打印机一般是没有自带驱动的,需要我们去安装驱动,怎么安装驱动才是用户最想要知道,下面,小编就给大家 ...
最新文章
- Linq初级班 Linq To XML体验(基础篇)
- 收藏|图神经网络综述
- Docker / 深入理解的容器和镜像
- 【IDEA】2020 断点(BreakPoints)调试(亲测)
- 【转】SQL注入攻击防御深层思考
- 在LINUX 下安装 Realtek 8110SC 千兆网卡驱动
- 【14】GO语言的接口类型
- Dijkstra算法介绍+正确性证明+性能分析
- 垂直居中——登录界面
- 神奇的python(六)之python的串口操作(pyserial)
- 关于iOS 'The sandbox is not sync with the Podfile.lock'问题解决方法
- 在Linux下安装LaTeX+CJK+中文字体的方法 [转]
- UML类图关系大全【转】
- 发现一个特给力的编写HTML/CSS的插件——Zen Coding
- 计算机耗材管理系统,办公用品(消耗品)管理系统 单机版
- Access数据库实用教程-----创建更新查询
- 为什么你玩lol遇到的队友都是坑(适用于所有moba游戏)
- 汉仪尚巍手书_汉仪尚巍手书字体
- JS 右键鼠标事件练习
- 中国网络游戏行业研究报告-2010