1. 程式人生 > >Linux下列印驅動的問與答

Linux下列印驅動的問與答

第一波

> 1>. 通過上面demo可知,這個適用於HP印表機,那我這裡想使用epson印表機,想使用ijsgutenprint,這裡也就要求移植gutenprint,

是的,是這樣的。需要移植gutenprint.

>   那請問在這裡,gutenprint 編譯僅只需要ijsgutenprint即可,還是同時需要其他什麼檔案(按照我的理解是同時需要其他檔案,但不知道其他配置檔案  應該如何設定)

是需要編譯gutenprint就可以了。

   2>. cups列印時,發現在設定印表機時會生成ppd檔案,請問該ppd檔案與印表機驅動有什麼關係?

正是由於cups才有了

ppdcups是一個大管家,全部型號它都管理,如何管理就是依靠的ppd檔案。Ppd檔案決定了cups在每一步應該派誰出場。

   3>. 按照我的理解,hpijsijsgutenprint等才是印表機的驅動,ppd 檔案在列印時起到什麼作用?

Hpijs ijsgutenprint僅僅是整個驅動中的九牛一毛而已.ppd檔案應用在cups在巨集觀調控時,比如決定在最後時刻呼叫hpijs還是ijsgutenprint

   4>. 請問命令: $ gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sOutputFile="/dev/lp0" ./tiger.ps -c quit

        中-sDeviceManufacturer -sDeviceModel 是根據什麼規則生成的?

這個是hpijs中寫的。由於hpijs開發時間比較早,新的型號驅動中並沒有,所以對於這裡使用型號“deskjet 5550”是試出來的。

20140926更:補充網友的提問

第二波

     最近也想在Exynos4412-Linux3.5平臺上實現USB印表機功能,現具備條件如下: (1)惠普HP Deskjet 1000 J110a 彩色噴墨印表機一臺 (採購中,機器還未到) (2)自己靜態編譯的ghostscript-9.04軟體和hpijs軟體 (3)4412-Linux開發平臺        我使用的編譯器是友善之臂提供的arm-linux-gcc-4.5.1,支援基於ARM v7指令集,問題如下:
 (1)我只需要在Linux下實現,配置編譯核心支援USB印表機,也能自動建立lp0裝置檔案。剩下的工作是不是執行如下命令即可?         gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sOutputFile="/dev/lp0"   /xxx/sample.ps -c quit 是的,直接執行就可以了。但是注意/xxx/sample.ps是要列印的檔案。不要認為是命令中固定中的一部分。        是不是在執行此條命令前還要做些準備工作,如建立tmp目錄等,但是直接在Linux下就有tmp目錄呢,還需要準備一些庫嗎? 你的是標準的嵌入式Linux不需要建立這些東西,我移植到不標準的Linux的系統中如Android中沒有/tmp目錄才需要自己建立一個。 (2)我插上USB印表機後直接在dev目錄下生成的lp0裝置節點,不是在/dev/usb目錄下生成,是否一樣?      嗯,這個是一樣的,無論生成在哪裡。自己mknod建立也是可以的,對應的驅動原始碼都是核心中的usblp.c這個檔案在kernel原始碼中有些年頭沒有更新了,我估計。 (3)上面那條命令是不是隻針對HP Deskjet 1000 J110a這一款印表機,其他印表機應該如何適配? hpijs原始碼中有一個檔案描述了它支援的所有的印表機型號,替換-sDeviceModel中就可以了。那麼你會問"deskjet 5550"而不是"deskjet 1000",是因為hpijs在很早都不維護了,deskjet 1000是近幾年才上市的型號,不可能存在於hpijs中。但是都是一些換湯不換藥的新型號,把老的型號中一個一個試試可以試中。:) (4)現在我只是先實現,即用Exynos4412--Linux平臺能控制USB印表機,後面的維護才是開始(比如實現較好的列印質量等等),那麼我應該學習什麼資料? 是的,會編譯並實現列印其實和在PC上所謂的技術宅們會配置印表機驅動是一樣的,沒有什麼深的技術,都是些熟能生巧的東西。 但是要想列印的好,就要了解其原理。印表機語言PDL 也叫頁面描述語言,這種實現僅僅是將固定格式(pdf or ps(postscript))的檔案轉換成頁面描述語言傳輸給印表機,而面對使用者的是txt word jpg png exl ppt等等各種格式,怎麼把它們處理好成「固定格式」也是重點。再給一些關鍵詞:PPI DPI PDL PPD CUPS POSTSCRIPT GUTENPRINT ...。 enjoy it.

第三波

1 . 我使用Linux3.5,那麼在Linux下USB印表機子系統是不是就只有你上面提到的usblp.c原始檔?沒有其他的了? 核心做的工作更單一,只是把「最終的資料」傳輸到印表機。可以從這個連結來看它被修改的歷史usblp.c。核心只提供這個,核心才不管你是什麼型號印表機要什麼資料呢,畢竟它只是核心。它只做大家都通用的功能。
2 . 我手上有臺佳能的MF4830d鐳射一體印表機,插上開發板後控制檯輸出這款印表機相關資訊。我想問的就是這些印表機資訊是Linux核心本身就有的,還是插上USB接 口後由印表機把這些印表機廠家等資訊給核心,然後核心識別到再輸出資訊?
USB裝置都是要自報家門的。usb協議中有專門的列印協議,核心是「不生產資訊只是軟硬體之間的搬運工」。型號的區別是通過執行sudo /usr/lib/cups/backend/usb輸出的資訊來區別的。而不是印表機貼的誰家的Logo。 3 . 那麼在Linux核心層面,USB印表機的驅動就只需要usblp.c就可以了嗎?看懂這個驅動我會收穫哪些?看懂這個驅動我要具備哪些知識?(先了解個框架) 我也沒有完全看懂,也不需要看懂 很成熟的東西好些年都不大變;不過看懂也不錯,可以讓你理解了核心usb通訊的實現方式。使用核心的usblp.c只是因為它是個通道,不是目的,目的是將資料傳輸給印表機。使用libusb(應用層的usb通訊庫)直接傳輸也是一樣的,參見hplip的實現;真到Android中使用usb host api也是一樣的,參見Google play中 USB列印APP 的實現。當然以上幾種方案我都有實現驗證的,因地制宜就好。 4 . 從上面的提問中你能幫我總結下我在哪方面的知識比較欠缺?比如是Linux下核心驅動?還是USB協議? 
如果是採用了usblp.c這種方式,核心驅動不需要任何考慮。USB協議也是無需任何的考慮。那都不是重點。重點是「在應用層如何處理好列印資料」。多搜尋上篇中提到的那幾個關鍵詞就好,那就是應用層列印相關的。不過也建議遇到什麼問題再找什麼解決方案也不錯,畢竟用不到時就去了解,會沒有目的。

20141010更:

4波: 

    你好,前段時間根據你的思路實現了ARM-LINUX平臺下的USB印表機,使用方案是gs-hpijs,印表機為deskjet1000。對這塊非常感興趣,再次諮詢幾個問題:

1.  大致瞭解了下,在Linux列印系統中,只要Linux核心支援USB列印通訊協議,然後使用列印系統 CUPS→gs→hpijs就可以在命令列上輸入命令進行列印了,問題是三個軟體都移植了,而只使用了gshpijs就可以實現命令列列印了,而CUPS不知道是如何呼叫gs軟體的,也不知道如何用,請指點一二?(只大概認為gs通過ijs介面呼叫hpijs)

這就要用到之前提到過「ppd檔案」,需要新增「印表機」到cups中,這個過程中要指定ppd檔案(包含在hpijs原始碼中),這樣就可以使用通用的lpr xxx.ps命令來列印了。Cups會自動根據ppd檔案中呼叫之前手動執行的列印命令。

2. hpijs是針對惠普公司的噴墨印表機驅動,如果我要在ARM-LINUX平臺上實現愛普生、佳能印表機,是不是還是可以使用gs--xxx方案,這個xxx可以是其他驅動?

Gutenprint中包含了一個ijsgutenprinthpijs類似的基於ijs的實現,可以支援市面上各個廠商70%印表機型號。

3. 命令列列印時,都是把ps格式的檔案送給/dev/lp0,如果要列印常用的txtjpg等格式的檔案時,應該把txtjpg檔案先轉換為ps格式的檔案,然後再用命令列列印,可以使用gs軟體轉換嗎?不知道怎麼轉換,沒有一點思路,請提醒一下.

Ps格式是比較原始的 中間格式,Gs同樣支援PDF格式作為 中間格式,txt,jpg等格式檔案轉換成PDF就相對容易了。整體思路就是先使用其它庫或者工具將常見格式如txt,jpg等等轉換為PDF,接下來交給GS處理就好了。

4. 我想深入理解,而只看了gshpijs軟體原始碼中的說明文件,需要看gshpijs軟體的原始碼嗎?如何下手?

這些開源專案很成熟,個人目前看法是會用就好。


還有一些東西也存在這裡吧:

嵌入式Linux開發板:

-dFirstPage=2 -dLastPage=3

/system/usr/bin/gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sstdout=%stderr -sOutputFile="/dev/lp0" /sdcard/ruler.pdf -c quit

/system/usr/bin/gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sstdout=%stderr -sOutputFile=- - < /sdcard/ruler.pdf > /dev/lp0

/system/usr/bin/gs \

-sDEVICE=ijs \

-sIjsServer=hpijs \

-dIjsUseOutputFD \

-sDeviceManufacturer="HEWLETT-PACKARD" \

-sDeviceModel="deskjet 5550" \

-r300x300 \

-dNOPAUSE \

-dSAFER \

-sstdout=%stderr \

-sOutputFile=- - < \

/sdcard/ruler.pdf \

> /dev/lp0

Android

/system/usr/bin/gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sstdout=%stderr -sOutputFile="/dev/usb/lp0" /mnt/external_sd/chinese.pdf -c quit

gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sstdout=%stderr -sOutputFile=- - < /mnt/external_sd/chinese.pdf > /dev/usb/lp0

PC

/system/usr/bin/gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sOutputFile="/dev/usb/lp0" /home/kangear/Work/Printer/res/Ruler/ruler.pdf -c quit

gs -sDEVICE=ijs -sIjsServer=hpijs -dIjsUseOutputFD -sDeviceManufacturer="HEWLETT-PACKARD" -sDeviceModel="deskjet 5550" -r300x300 -dNOPAUSE -dSAFER -sstdout=%stderr -sOutputFile=%stdout  ~/HelloWorld.pdf -c quit > HelloWorld.PCL3GUI