顯示具有 PHP 標籤的文章。 顯示所有文章
顯示具有 PHP 標籤的文章。 顯示所有文章

2009年3月19日 星期四

ghostscript + imagemagick

之前我一直在用 magickwand 或是 iMagick 在做轉檔的動作
但是 這兩個方式在轉 eps 或是 pdf 這類向量檔的時候卻是力有未逮
東試西試 終於在我的server上面搞定了 把eps 轉成 png 可以很漂量很平順
但是 顏色就不見得準了 (這牽涉到另一個問題)

我花了很長的時間研究 imagemagick到底在處理EPS的時候是否需要 ghostscript
甚至在 imagemagick 的討論版上都有人提到為什麼轉出來的畫質如此之差
但是並沒有人真正提出解決方式
基本上 如果你不挑剔畫質 那麼 單就處理EPS這種檔案的時候是不需要 ghostscript 的
其結果就像這樣 (圖一)












因為EPS在存檔的時候就已經預存了一段預視檔
用來提供給不能處理向量圖檔的電腦使用
譬如 一般的文書處理電腦也可以在WORD裡貼入EPS檔
或者即使電腦可以處理向量圖檔 也可以減輕電腦壓力
所以 即使不賦予電腦有處理向量圖檔的能力 ( 安裝 ghostscript ) imagemagick 也可以輕鬆把預視檔讀出來
安裝了 ghostscript 之後 imagemagick 就可以把實際的向量內容讀出(也才能轉檔)
所以 這關鍵在於 該電腦有沒有處理向量圖檔的能力
(圖二)













依樣畫葫蘆的 在我工作的電腦上 也安裝了 ghostscript 與 imagemagick
但是很神奇的是 好像這兩個軟體突然之間不認識了
也就是轉出來(PHP的 EXEC() 或是 我另外的轉檔程式)的結果都跟圖一一樣
但是 卻可以在CMD下轉出同樣的畫質 (圖二)
花了好幾天的時間安安裝裝 裝裝安安 當然還是有吃飯睡覺
我思我想我判斷是~~~~
我的工作電腦有安裝 illustrator 所以 檔案的關聯被關連到 illustrator
以至於 imagemagick即使是裝了 ghostscript 這義肢 卻還是跛腳

到這幾天 我更新了我的SERVER
在新機器上 ghostscript 與 imagemagick 又好像不認識了
安安裝裝 裝裝安安了好幾次 還是不行
當然 SERVER 是不可能平白無故裝 illustrator
這下可就沒有推卸責任的理由了
於是 我只好讓兩台機器立正站好 看看有什麼不同

一樣的 IIS 6
PHP 5.26
MySQL 5............ 媽的 跟 MySQL 有什麼關係

重點來了
舊機器是 imagemagick 6.3.6-10-Q16 + ghostscript 8.53
新機器是 imagemagick 6.4.9-2-Q16 + ghostscript 8.53

那就在新機器上改用舊版的試試看吧
重裝之後重新開機
ㄟ~~~~~ 可以了耶
不信邪
我又翻了一下我工作機 沒錯也是 imagemagick 6.4.9-2-Q16
但是 ghostscript 是 8.63

好吧 也請舊版的來好了
換上舊版 (6.3.6-10-Q16) ㄟ 可以了
所以 是什麼問題呢
我覺得應該是有版本搭配上的問題
但是為什麼新版的 imagemagick 抓不到舊版的東西呢
我的程式都是一樣的 都是使用 imagemagick class 來處理
(因為當時想要跟 imagick 使用同樣的操作介面 所以捨棄使用 exec() )

(圖三)












至於顏色的問題
這三張轉出來的結果 其實都是同一個EPS所轉的
都是CMYK的色彩模式
但是 圖三的顏色為什麼差這麼多
那就是少了 -colorspace RGB 這個設定
但是更保險的方式其實應該是要先把EPS轉為PDF 並且改為 RGB模式
再把PDF轉為 JPG或是PNG
當然 如果你需要的是 CMYK模式的JPG 那麼 就可以忽略掉這設定
但是呢 在一拉屎 10 之前的存檔................
應該怎麼說呢
一拉屎10 之前的版本 所存的檔案 其實 顏色沒有那麼的精準
或者說 他單純只考慮了 CMYK的模式 並未考慮到 RGB的顯示
因為在一拉屎 9 的階段對於網頁圖片的支援是非常差的
所以 即使是 EPS >> PDF >> PNG 或是下 colorspace 都是沒什麼太大的用處

問我為什麼只提到一拉屎??? CoralDRAW 也只能匯出 一拉屎7的格式 所以就~~~~~~~~
Quark也可以出EPS阿?? 但是 有多少人看過 用過 Quark的EPS 大概只有印刷廠的人吧
indesign呢?? 他跟一拉屎是一家人 還會有多少差別 更何況 現在會使用indesign的人都是出PDF輸出了 誰還會出EPS去自找麻煩

囉囉唆唆講了一堆 重點是 ghostscript + imagemagick 並不是什麼版本拿來裝了都可以的
但是 這僅限於我的電腦 我經手的電腦 歡迎各位做參考
不要認為你的電腦也同樣可以 因為 我甚至不知道你的機箱是黑的還是白的

2008年10月28日 星期二

ColorSpace 一個看起來好像很有用 但是沒用的玩具

上一篇只講到 有關於JPEG如何判斷檔案的色域是RGB或是CMYK
如果 僅僅是為了顯示圖片在瀏覽器上 那篇就絲毫沒有用處
可是如果是用來做影像管理 圖庫這類的東西 那是大大的不足

印刷與顯示的需求差異很大
印刷要求的是 CMYK 300dpi
而顯示要求的是 RGB 72dpi
也許 在儲存上 還是要以 CMYK 300dpi來儲存 但是在網頁顯示上 卻需要 RGB 72dpi

所以 就必須要有 檢查色域與改變色域的功能
而這兩個功能都是imagemagick所擁有的

以下是每個色域的代號
ColorspaceType constants
0 MW_UndefinedColorspace
1 MW_RGBColorspace
2 MW_GRAYColorspace
3 MW_TransparentColorspace
4 MW_OHTAColorspace
5 MW_LABColorspace
6 MW_XYZColorspace
7 MW_YCbCrColorspace
8 MW_YCCColorspace
9 MW_YIQColorspace
10 MW_YPbPrColorspace
11 MW_YUVColorspace
12 MW_CMYKColorspace
13 MW_sRGBColorspace
14 MW_HSBColorspace
15 MW_HSLColorspace
16 MW_HWBColorspace

由於 PHP 5.2.6 之後就可以安裝 imagick 所以 我把同樣的功能寫成兩個不同的函式
一個是在 imagick 上使用 一個是在 magickwand 上使用

function IM_ColorSpace_Check($file){
$image=new Imagick($file);
$ColorspaceType = $image->getImageColorspace($file);
return $ColorspaceType;
}

imagick 傳回的是一個數值 例如 12 代表 CMYK

function MW_ColorSpace_Check($file){
$mgck_wnd = NewMagickWand();
MagickReadImage($mgck_wnd, $file);
$ColorspaceType = MagickGetImageColorspace($mgck_wnd);
return $ColorspaceType;
}

magickwand 傳回的是一個功能變數 例如 MW_CMYKColorspace 代表 CMYK 當然也就是 12

其實我個人發現 這16個色域 絕大部分是很少用到的 可卻也缺少一個 index color
這是GIF的格式

function IM_ColorSpace_Change($file, $ColorspaceType, $outputfile = False){
$image=new Imagick($file);
$image->setImageColorspace($ColorspaceType);
if ($output == False){
$image->writeImage($file);}
else{
$image->writeImage($outputfile);}
}

function MW_ColorSpace_Change($file, $ColorspaceType, $outputfile = False){
$mgck_wnd = NewMagickWand();
MagickReadImage($mgck_wnd, $file);
MagickSetImageColorspace($mgck_wnd, $ColorspaceType);
if ($outputfile == False){
MagickWriteImage($mgck_wnd);}
else{
MagickWriteImage($mgck_wnd, $outputfile);}
}

同樣的 一個是給 imagick 上使用 一個是給 magickwand 上使用

看起來是乎很方便 但是試過之後就會發現 這功能完全不能用
在網路上也幾乎沒有找到有這方面的範例
RGB的色域較廣 所以 可以轉換到CMYK的時候 有些顏色就會消失 某些圖片看起來會比較暗沉
而色域較小的CMYK 轉換到 RGB的時候 卻可以完全轉換
這個差異大家可以用Photoshop試試看就知道了
當然我不強求 RGB to CMYK的時候會有多漂亮
但是 CMYK to RGB 卻不能變化太多
可是 試驗下來 卻發現 通通會變色 而且差異蠻大的
這樣一來 還能用嗎
我知道 RGB to CMYK 的時候 先轉換為 index color 顏色掉得比較少
可是 卻沒有 index color 可以中介轉換
試了之後 我只能說 色域轉換個功能是玩具

2008年10月25日 星期六

Get Image ColorSpace CMYK or RGB

用過 ImageMagick的人都知道 ImageMagick 的功能比GD2 多很多
但是 如果在別人的伺服器上沒有安裝 ImageMagick 的時候要怎辦

我自己寫了一個個人相簿 主要是有些圖像整理起來需要用到特殊的功能
包括 300dpi的問題 cmyk的問題
當然這些東西 如果安裝了 ImageMagick 那一切好辦事
但是如果沒有呢

找了好幾天 才發現 其實 GD的 getimagesize 就有這樣的功能
當然 他僅限於 JPEG 其他的 TIFF 他根本就沒支援
但是這樣也夠了 因為 TIFF根本不能顯示在網頁上
而JPEG (CMYK) 也不能顯示在網頁上
那一但上傳了 JPEG (CMYK) 就需要做轉換
至於其他可以在網頁上顯示的 GIF 與PNG 都是RGB 根本也無須判別

先用以下的涵式看看 getimagesize 取得哪些資料

function CheckColorSpace($file){
$imagedata = getimagesize($file);
foreach ($imagedata as $val){
echo $val;
}
}

先整裡兩個JPEG檔 一個為RGB 一個為CMYK

分別呼叫這個涵式之後
會發現
-----------------RGB-------------------------
1600
1200
2
width="1600" height="1200"
8
3
image/jpeg
-----------------CMYK------------------------
1600
1200
2
width="1600" height="1200"
8
4
image/jpeg

Array[0] = Width
Array[1] = Height
Array[2] = Image Type Flag
Array[3] = width="xxx" height="xxx"
Array[bits] = bits
Array[channels] = channels
Array[mime] = mime-type

通常我們用到的 只是 第0 與第1個 索引 也就是寬與高
第2索引 是圖片類型的判斷
第3索引 則是以文字表現寬高
第4索引 每個像素用幾個bit表示
第5索引 如果為3 則表示 這個圖像由3個 channel組成 所以為RGB
如果為4 則表示 這個圖像由4個 channel組成 所以為CMYK
這個索引式JPEG特有的
第6索引 IMAGETYPE 可直接給 HTTP Content-type header使用

由此就可以判斷出 這個JPEG 是CMYK 還是RGB

function GD_CheckColorSpace($file){
$imagedatas = getimagesize($file,$imageinfo);
if ($imagedatas[2] != 2){
$CheckColor = "RGB";
}
else{
if ($imagedatas[channels] == 3){
$CheckColor = "RGB";
}
elseif ($imagedatas[channels] == 4){
$CheckColor = "CMYK";
}
}
return $CheckColor;
}

以下是 ImageMagick 判斷色域的涵式

function MW_CheckColorSpace($file){
$mgck_wnd = NewMagickWand();
MagickReadImage($mgck_wnd, $file);
$img_colspc = MagickGetImageColorspace($mgck_wnd);
//echo $img_colspc;
switch ($img_colspc){
case MW_CMYKColorspace :
return "CMYK";
break;
case MW_sRGBColorspace :
return "sRGB";
break;
case MW_RGBColorspace :
return "RGB";
break;
case MW_GRAYColorspace :
return "GRAY";
break;
case MW_LABColorspace :
return "LAB";
break;
//default:
}
}

兩者個功能差很多 當然 使用GD是不得已的作法