虚拟打印

 虛擬打印技術研究報告

1        總述

1.1      什麼是虛擬打印?

到底什麼是虛擬打印呢?簡單來說,虛擬打印就是在操作系統中虛擬出來一個打印機,這個虛擬出來的打印機可以將所有可打印的文檔打印成BMP圖像。文檔的格式通常可以是多種多樣的,一般的office系列和其他名稱的檔案,只要是可以在實際的打印機上打印出來的東西,都可以進行使用。

1.2      虛擬打印有什麼好處?

那麼,虛擬打印能夠給我們帶來什麼好處呢?虛擬打印在協同工作方面有著廣泛的作用。舉例來說,你可以將一個WORD文檔打印成BMP圖像,然後發送給其他人,其他人即使沒有安裝相應的閱讀軟件,也可以瀏覽,甚至修改檔案。這樣的話,就解決了由於系統安裝軟件的差異帶來的兼容性問題。

2        原理

主要思路如下:

1.          首先當然是必須要在系統中虛擬出來一個我們自己的打印機,並且在打印文檔的時候把我們的打印機設置成默認的,這樣待打印的文檔的數據流才能夠被我們所截獲。對於這一點來說,安裝打印機的話,Windows系統有自帶的API函數來執行,但是需要我們提供打印機的驅動程式,這個是最關鍵的。

2.          對於打印機的驅動程式來說,從參考的DDK的說明來看,微軟提供了一個通用的打印機驅動程式,這個驅動程式是微軟設計的標準的打印機驅動程式。這樣的話,驅動程式的問題也解決了,打印機可以安裝起來了。但是因為驅動程式是用的現成的,無法獲的打印文檔的數據流。

3.          好在對於上面的微軟的通用驅動程式,並沒有完全做死,允許用戶按照一定的接口標準來做一個插件,來進行與驅動程式的交互。甚至是可以獲得數據流,這樣的話,我們完全可以把數據流存成我們自己的BMP文件。

4.          通過上面的分析,整個思路已經完全清楚了。通過對DDK的進一步分析,我們得到如下的一些信息:

使用通用打印程式的打印流程可以概括如下:

由上圖可知,微軟的通用打印驅動程式主要包含兩大塊的組件,其中一個是unidrvui.dll,這個組件負責提供上層的用戶接口,允許用戶設置打印的一些屬性。另外一個是unidrv.dll,這個組件負責從windows的圖形生成器中獲得數據流,然後轉給打印機。另外我們可以看到兩個可選的插件,一個是User interface Plug-in,主要是基於屬性頁和樹型控件的用戶接口,能夠改變打印機的一些屬性,主要是與unidrvui.dll這個組件交互。另外一個是Rending Plug-in,一個配合GDI圖形生成器的單獨的實現插件,將應用程序中對GDI的調用轉化為打印機命令,主要是與unidrvui.dll這個組件交互。這樣的話就是非常明確的一件事情了,我們的主要任務就是實現一個Rendering Plug-in的插件,然後利用這個插件獲得圖形數據流,最後保存到文件當中。

3        實現

1.          對於安裝打印機來說,Windows具有一組API可以直接進行安裝:

l          GetPrinterDriverDirectory獲的打印機驅動程式的目錄,並且將要裝的驅動程式拷貝到這裡。

l          AddPrinterDriver首先安裝打印機驅動程式

l          AddPrinter安裝打印機,使用上面安裝好的驅動程式

l          SetDefaultPrinter設置成為默認的打印機

l          DeletePrinter卸載時將打印機刪除

2.          對於編寫Rending Plug-in這個插件來說,在DDK裡面有一個現成的例子,但是這個例子只是實現了一個框架而已,什麼事情都不做。這樣的話,我們需要改造這個例子,使她首先從驅動程式那裡獲取數據流,然後把數據流保存成標準的BMP文件。

l          首先我們必須要與驅動程式交互,這樣的話,我們必須要暴露接口,然後驅動程式就會把數據流傳到我們的插件裡面來。在這裡我們只要暴露ImageProcessing這個接口,這就告訴了驅動程式,我需要對圖像進行進一步的處理,請將圖像數據傳給我。這樣的話,驅動程式就回調這個函數,把圖像數據數據傳過來。

l          然後有必要對打印的流程介紹一下,一般來說基于unidrv,使用gdi管理表面的驱动程序一般都有这样的处理流程:

enabledriver-----init undrv driver
enablePDEV-----init PDEV structure
startdoc
startpage
if(use banding)//
驱动程序是否使用banding是动态决定的,取决于数据量的大小
{
startbanding
while(NOT at the end of page)
{
drawing(blt, path or text)
(pre-process, callback to unixxx, post-process)
nextband
if(use imageprocess) //
如果此接口存在
{
imageprocess----
可以在这里得到bmp数据

}
}
}
else
{
drawing(blt, path or text)
(pre-process, callback to unixxx, post-process)
sendpage
if(use imageprocess) //
如果此接口存在
{
imageprocess
}
}
enddoc
disablePDEV
disabledriver

3.          這樣的話,我們已經獲取到圖像數據,最後我們就只要把它們保存成文件就可以了,這裡我們根據每一個掃描行逐行寫入,最後再加上位圖文件頭。至此打印的全部流程都已經完成了。

4        存在的問題

目前還剩下如下問題需要改善:

l          目前只支持默認的A4紙張的大小,打印出來的圖像大小為2338*1654,後面希望能夠支持更多的格式。

l          沒有對所有可打印出來的文檔進行測試過,有可能個別的文檔打印出來會有問題。

l          目前只支持BMP格式,後續考慮支持jpg等多種格式。

 

---End of file---

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值