背景:
預告了好久的幾篇專欄博文一直沒有整理好,主要原因是早前希望搭建的WML服務器計划遇到了問題。起初以為參照DCMTK的官方文檔wwwapp.txt結合前兩天搭建的WAMP服務器可以順利的實現WML服務,借此就可以同時完成WEB PACS系列以及搭建Dicom WML服務器的兩篇博文。可是在實際部署過程中發現了幾個嚴重的問題,一時無法解決。但是在搜索解決方案的時候,偶然間找到了在DCMTK論壇上貼出來的用PHP對DCMTK工具包封裝的文章。因此此篇博文在記錄搭建WML遇到的問題的同時,主要想向大家介紹一下這個簡單的封裝DCMTK工具包的PHP類,並在前期搭建的WAMP服務器上給出示范實例。(PS:也希望知道如何解決該問題的大神趕緊現身)
問題:
按照DCMTK官方文檔wwwapp.txt文件(http://support.dcmtk.org/docs/file_wwwapp.html)的說明,搭建DICOM Basic Worklist Management服務的前期准備工作已經基本完成,前述的WEB PACS平台已經能夠順利提供HTTPD、CGI以及Perl解析的功能(具體可參見博文中給出的Perl示例:http://blog.csdn.net/zssureqh/article/details/40516745)。但是按照wwwapp.txt文檔指示拷貝wwwapps目錄下的可執行文件(例如preplock、readoviw、readwlst、writwlst)時,並未在編譯后的工程中找到,只看到了相應的.cc源碼文件。
wwwapp安裝的相關資料:
嘗試解決:
按照上述的說明,確信應該是在編譯DCMTK源碼中間的某個環節出現了問題,導致本應該順利生成的幾個exe文件丟失。官方論壇中的討論是針對Linux環境下利用make工具來編譯的情況,該環境下在利用make安裝的時候由make distclean指令來控制preplock、readoviw、readwlst、writwlst等可執行文件的清除。但是在Windows環境下用的是CMake來生成與VS對應的sln文件,打開DCMTK.sln解決方案后並未找到如何設置才能編譯生成上述可執行文件,而且按照柳前輩的說法,即使編譯成功,在Win7環境下同樣缺少一個preplock.exe文件。至此該問題的解決就終止了,到發文時刻還未找到很好的解決方法。
PHP DICOM Class
在瀏覽OFFIS論壇,尋找上述問題的解決方案時,無意點開了論壇中的“Third-Party DCMTK Applications”分支,如下圖所示,該分論壇中介紹了眾多DCMTK相關的應用開發,其中有一項叫做“PHP DICOM Class“。
其中作者Vedicveko給出了PHP Dicom Class類的設計初衷以及詳細的使用說明,說明文檔網址為:http://deanvaughan.org/wordpress/dicom-php-class/。
下載源碼(https://github.com/vedicveko/class_dicom.php/zipball/master)后,打開class_dicom.php核心類文件,可以看出作者通過使用PHP中的exec命令來對DCMTK對應的工具包進行了封裝,借助於PHP語言的優勢使得DCMTK更易於網絡化應用。Apache網絡服務器與PHP之間的調用可以直接利用我們前面搭建的簡易WEB PACS平台(該平台對於PHP的調用通過FastCGI來實現),然后通過結合PHP DICOM Class可以實現對dcm文件的大多數操作,具體的實現如下。
PHP DICOM Class的安裝:
第一,將DCMTK編譯后的工具包統一放到指定位置,例如我的本機地址為:c:\dcmtk\bin,修改class_dicom.php文件中的如下代碼,將TOOLKIT_DIR指向本機工具包目錄c:\dcmtk\bin。
define('TOOLKIT_DIR', 'C:/dcmtk/bin'); // CHANGE THIS IF YOU HAVE DCMTK INSTALLED SOMEWHERE ELSE
第二,借助前面搭建的WAMP服務,在網站服務根目錄(我本機為c:\wamp\www\)下新建class_dicom_php目錄,將下載的PHP DICOM Class源碼文件直接拷貝到class_dicom_php目錄下,如下圖所示:
第三,開啟wamp server服務,在瀏覽器中輸入http://localhost/class_dicom_php/examples/get_tags.php,進行測試,正常的話會輸出dean.dcm文件的Tags標簽信息,如下圖所示:
如上所示瀏覽器中看到的結果與利用dcmdump.exe工具查看的結果一致,說明PHP DICOM Class已經順利的安裝到了WEB PACS平台中。
【注】:在實際運行過程中可能會出現錯誤,原因是get_tags.php中使用的是$argv命令行變量來獲得具體的dcm文件路徑的,但是在WEB PACS中我們只能通過GET或者POST方式傳遞參數到php腳本,因此可修改get_tags.php中的參數獲取方式,或者直接將測試文件dean.dcm寫入到文件路徑變量中,如下所示:
$file = (isset($argv[1]) ? $argv[1] : 'dean.dcm');
#原來代碼為:$file = (isset($argv[1]) ? $argv[1] : ' ');
示例:向瀏覽器輸出DCM圖像數據
1)添加dcm_to_bmp()函數:
雖然PHP DICOM Class只是簡單的調用了DCMTK工具包來實現PHP對DICOM文件的操作,但是由於DCMTK工具包的強大,在目前我們簡易的WEB PACS平台的並發數不大的情況下,可以嘗試直接利用PHP DICOM Class來實現前篇博文中將DCM文件的圖像信息輸出到瀏覽器的功能。
查看class_dicom.php,看到其中dicom_convert類中有關於JPEG到DCM的自由雙向變換,其源碼中用到的是DCMTK工具包中的dcmj2pnm,查看dcmj2pnm的幫助文檔可知,該工具也可實現DCM到bmp文件的轉換,因此決定對class_dicom.php中的dicom_convert類進行擴展,添加dcm_to_bmp()函數,具體代碼如下:
### zssure 20141104
function dcm_to_bmp() {
$filesize = 0;
$this->jpg_file = $this->file . '.bmp';
$convert_cmd = BIN_DCMJ2PNM . " +ob " . "\"" . $this->file . "\" \"" . $this->jpg_file . "\"";
$out = Execute($convert_cmd);
if(file_exists($this->jpg_file)) {
$filesize = filesize($this->jpg_file);
}
return($this->jpg_file);
}
dcm_to_bmp()不同於dcm_to_jpg()的主要地方是dcmj2pnm的指令參數不同,bmp文件用到的是+ob參數,dcmj2pnm本身可以生成多種格式的bmp圖像,如下圖所示:
當然也可以通過識別dcm具體的圖像標簽來自動設定保存的bmp格式,在自適應時刻用到的主要標簽如下圖所示:
2)實例測試:
編寫dcm_to_bmp的測試php,代碼如下:
#!/usr/bin/php
#
# Creates a jpeg and jpeg thumbnail of a DICOM file
#
require_once('../class_dicom.php');
$file = (isset($argv[1]) ? $argv[1] : 'dean.dcm');
if(!$file) {
print "USAGE: ./dcm_to_jpg.php \n";
exit;
}
if(!file_exists($file)) {
print "$file: does not exist\n";
exit;
}
$job_start = time();
$d = new dicom_convert;
$d->file = $file;
$d->dcm_to_bmp();
#$d->dcm_to_tn();
#system("ls -lsh $file*");
$job_end = time();
$job_time = $job_end - $job_start;
#print "Created BMP and thumbnail in $job_time seconds.\n";
header("Content-type:image/bmp\n\n");
$jpgName=$d->jpg_file;
$fp=fopen($jpgName,"r");
fpassthru($fp);
exit;
?>
在利用dcmj2pnm將dcm轉換成bmp文件后,就可以直接利用前面博文中PHP輸出圖像到瀏覽器的代碼來輸出結果,在瀏覽器中輸入:http://localhost/class_dicom_php/examples/dcm_to_bmp.php,順利得到dean.dcm測試文件的圖像信息,如下圖所示:
至此,利用PHP DICOM Class快速便捷地實現了將dcm文件的圖像信息輸出到瀏覽器的功能。
【注】:在上述dcm_to_bmp.php測試文件中需要將#system("ls -lsh $file*");語句注釋掉,否則在windows的WAMP環境下會出現問題。
學習DCMTK的資料:
原來只是利用OFFIS的論壇(http://forum.dcmtk.org/index.php)來搜索使用DCMTK過程中遇到的各種錯誤,從來沒有仔細全面的瀏覽過OFFIS論壇的各個部分,通過今天的親身經歷,發現在OFFIS論壇的DCMTK項目下的【Third-Party DCMTK Applications】部分也是一個知識寶藏,里面包含了各種牛人利用DCMTK開發的工具,大多都是開源的,相關文檔也很詳細,以后可以作為重點學習的資料。
下面給出幾個我覺得很值得學習的鏈接,供大家參考:
后續博文介紹:
利用PHP Skel結合DCMTK開發WEB PACS應用
利用DCMTK搭建WML服務器
利用Oracle直接操作DICOM數據
C#的異步編程模式在fo-dicom中的應用
VMWare三種網絡連接模式的實際測試