--- /dev/null
+<?php\r
+/**\r
+ * Thumbnail Generate API: GD Wrapper\r
+ *\r
+ * 提供程式便於以 GD Library 生成預覽圖的物件\r
+ *\r
+ * @package PMCLibrary\r
+ * @version $Id: thumb.gd.php 603 2008-02-22 14:12:29Z scribe $\r
+ * @date $Date: 2008-02-22 22:12:29 +0800 (星期五, 22 二月 2008) $\r
+ */\r
+\r
+class ThumbWrapper{\r
+ var $sourceFile, $sourceWidth, $sourceHeight, $thumbWidth, $thumbHeight, $thumbQuality;\r
+\r
+ function ThumbWrapper($sourceFile='', $sourceWidth=0, $sourceHeight=0){\r
+ $this->sourceFile = $sourceFile;\r
+ $this->sourceWidth = $sourceWidth;\r
+ $this->sourceHeight = $sourceHeight;\r
+ }\r
+\r
+ function _GetLeftShiftCount($dwVal,$len=4) {\r
+ $nCount = 0;\r
+ for ($i=0; $i<$len * 8; $i++) {\r
+ if ($dwVal & 1) $nCount++;\r
+ $dwVal >>= 1;\r
+ }\r
+ return (8 - $nCount);\r
+ }\r
+ function _GetRightShiftCount($dwVal,$len=4) {\r
+ for ($i=0; $i<$len * 8; $i++) {\r
+ if ($dwVal & 1) return $i;\r
+ $dwVal >>= 1;\r
+ }\r
+ return -1;\r
+ }\r
+\r
+ /* ImageCreateFromBMP : 讓GD可處理BMP圖檔\r
+ 此為修改後最適化版本。原出處:http://www.php.net/imagecreate#53879\r
+ 原作宣告:\r
+ *****************************\r
+ Function: ImageCreateFromBMP\r
+ Author: DHKold\r
+ Contact: admin@dhkold.com\r
+ Date: The 15th of June 2005\r
+ Version: 2.0B\r
+ *****************************/\r
+ function _ImageCreateFromBMP($filename){\r
+ // 序章:以二進位模式開啟檔案流\r
+ if(!$f1 = fopen($filename, 'rb')) return FALSE;\r
+\r
+ // 第一步:讀取BMP檔頭\r
+ $FILE = unpack('vfile_type/Vfile_size/Vreserved/Vbitmap_offset', fread($f1, 14));\r
+ if($FILE['file_type']!=19778) return FALSE; // BM\r
+\r
+ // 第二步:讀取BMP資訊\r
+ // 僅支援BITMAPINFOHEADER,不支援BITMAPV4HEADER及BITMAPV5HEADER\r
+ $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel/Vcompression/Vsize_bitmap/Vhoriz_resolution/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));\r
+ $BMP['colors'] = pow(2, $BMP['bits_per_pixel']);\r
+ if($BMP['size_bitmap']==0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];\r
+ $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;\r
+ $BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);\r
+ $BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4);\r
+ $BMP['decal'] = 4 - (4 * $BMP['decal']);\r
+ if($BMP['decal']==4) $BMP['decal'] = 0;\r
+\r
+ // 第三步:讀取色盤資訊\r
+ $PALETTE = array();\r
+ if ($BMP['colors'] <=256 || $BMP['compression'] == 3) {\r
+ if($BMP['compression'] == 3) // BI_BITFIELDS\r
+ $PALETTE = unpack('V3', fread($f1,12));\r
+ else\r
+ $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));\r
+ }\r
+ if($BMP['compression'] == 3) // BI_BITFIELDS\r
+ $mask = array(array($PALETTE[1],$PALETTE[2],$PALETTE[3]),\r
+ array($this->_GetRightShiftCount($PALETTE[1]),$this->_GetRightShiftCount($PALETTE[2]),$this->_GetRightShiftCount($PALETTE[3])),\r
+ array($this->_GetLeftShiftCount($PALETTE[1]),$this->_GetLeftShiftCount($PALETTE[2]),$this->_GetLeftShiftCount($PALETTE[3])));\r
+ else {\r
+ if($BMP['colors'] == 65536) $mask = array(array(0x7C00,0x3E0,0x1F),array(10,5,0),array(3,3,3));\r
+ }\r
+\r
+ // 第四步:關閉檔案,變換每一個畫素\r
+ $IMG = fread($f1, $BMP['size_bitmap']);\r
+ fclose($f1);\r
+ $VIDE = chr(0);\r
+\r
+ $res = ImageCreateTrueColor($BMP['width'], $BMP['height']);\r
+ $P = 0;\r
+ $Y = $BMP['height'] - 1;\r
+\r
+ if($BMP['compression'] == 1 && $BMP['colors'] == 256) { // BI_RLE8\r
+ $imgDataLen=strlen($IMG);\r
+ $RLEData='';\r
+ while(true) {\r
+ $prefix=ord(substr($IMG, floor($P++), 1));\r
+ $suffix=ord(substr($IMG, floor($P++), 1));\r
+\r
+ if(($prefix==0)&&($suffix==1)) break; // end of RLE stream\r
+ if($P>=$imgDataLen) break;\r
+\r
+ while(!(($prefix==0)&&($suffix==0))){ // ! end of RLE line\r
+ if($prefix==0){ // Command\r
+ $RLEData.=substr($IMG, floor($P), $suffix);\r
+ $P+=$suffix;\r
+ if($P%2==1) $P++;\r
+ } elseif($prefix>0){ // Repeat\r
+ for($r=0;$r<$prefix;$r++)\r
+ $RLEData.=chr($suffix);\r
+ }\r
+ $prefix=ord(substr($IMG, floor($P++), 1));\r
+ $suffix=ord(substr($IMG, floor($P++), 1));\r
+ }\r
+ for($X=0;$X<strlen($RLEData);$X++) // Write\r
+ ImageSetPixel($res, $X, $Y, $PALETTE[ord($RLEData[$X])+1]);\r
+ $RLEData='';\r
+ $Y--;\r
+ }\r
+ } elseif($BMP['compression'] == 2 && $BMP['colors'] == 16) { // BI_RLE4\r
+ $imgDataLen=strlen($IMG);\r
+ $RLEData='';\r
+ while(true) {\r
+ $prefix=ord(substr($IMG, floor($P++), 1));\r
+ $suffix=ord(substr($IMG, floor($P++), 1));\r
+\r
+ if(($prefix==0)&&($suffix==1)) break; // end of RLE stream\r
+ if($P>=$imgDataLen) break;\r
+\r
+ while(!(($prefix==0)&&($suffix==0))){ // ! end of RLE line\r
+ if($prefix==0){ // Command\r
+ for($h=0;$h<$suffix;$h++) {\r
+ $COLOR = ord(substr($IMG, floor($P), 1));\r
+ $RLEData.=($h%2==0)?chr($COLOR >> 4):chr($COLOR & 0x0F);\r
+ $P += $BMP['bytes_per_pixel'];\r
+ }\r
+ $P=ceil($P);\r
+ if($P%2==1) $P++;\r
+ } elseif($prefix>0){ // Repeat\r
+ for($r=0;$r<$prefix;$r++)\r
+ $RLEData.=($r%2==0)?chr($suffix >> 4):chr($suffix & 0x0F);\r
+ }\r
+ $prefix=ord(substr($IMG, floor($P++), 1));\r
+ $suffix=ord(substr($IMG, floor($P++), 1));\r
+ }\r
+\r
+ for($X=0;$X<strlen($RLEData);$X++) // Write\r
+ ImageSetPixel($res, $X, $Y, $PALETTE[ord($RLEData[$X])+1]);\r
+ $RLEData='';\r
+ $Y--;\r
+\r
+ }\r
+ } else {\r
+ while($Y >= 0){\r
+ $X = 0;\r
+ while($X < $BMP['width']){\r
+ switch($BMP['bits_per_pixel']){\r
+ case 32: \r
+ $COLOR = unpack('V', substr($IMG, $P, 4));\r
+ $COLOR[1] &= 0xFFFFFF; // 不處理Alpha\r
+ break;\r
+ case 24: $COLOR = unpack('V', substr($IMG, $P, 3).$VIDE); break;\r
+ case 16:\r
+ $COLOR = unpack("v",substr($IMG,$P,2));\r
+ $COLOR[1] = (((($COLOR[1] & $mask[0][0])>>$mask[1][0])<<$mask[2][0])<<16) |\r
+ (((($COLOR[1] & $mask[0][1])>>$mask[1][1])<<$mask[2][1])<<8) |\r
+ ((($COLOR[1] & $mask[0][2])>>$mask[1][2])<<$mask[2][2]);\r
+ break;\r
+ case 8: $COLOR = unpack('n', $VIDE.substr($IMG, $P, 1)); break;\r
+ case 4:\r
+ $COLOR = unpack('n', $VIDE.substr($IMG, floor($P), 1));\r
+ if(($P*2)%2==0) $COLOR[1] = ($COLOR[1] >> 4);\r
+ else $COLOR[1] = ($COLOR[1] & 0x0F);\r
+ break;\r
+ case 1:\r
+ $COLOR = unpack('n', $VIDE.substr($IMG, floor($P), 1));\r
+ switch(($P * 8) % 8){\r
+ case 0: $COLOR[1] = $COLOR[1] >> 7; break;\r
+ case 1: $COLOR[1] = ($COLOR[1] & 0x40) >> 6; break;\r
+ case 2: $COLOR[1] = ($COLOR[1] & 0x20) >> 5; break;\r
+ case 3: $COLOR[1] = ($COLOR[1] & 0x10) >> 4; break;\r
+ case 4: $COLOR[1] = ($COLOR[1] & 0x8) >> 3; break;\r
+ case 5: $COLOR[1] = ($COLOR[1] & 0x4) >> 2; break;\r
+ case 6: $COLOR[1] = ($COLOR[1] & 0x2) >> 1; break;\r
+ case 7: $COLOR[1] = ($COLOR[1] & 0x1);\r
+ }\r
+ break;\r
+ default:\r
+ return FALSE;\r
+ }\r
+ if($BMP['bits_per_pixel']<16) $COLOR[1] = $PALETTE[$COLOR[1]+1];\r
+ ImageSetPixel($res, $X, $Y, $COLOR[1]);\r
+ $X++;\r
+ $P += $BMP['bytes_per_pixel'];\r
+ }\r
+ $Y--;\r
+ $P += $BMP['decal'];\r
+ }\r
+ }\r
+\r
+ // 終章:回傳新圖像\r
+ return $res;\r
+ }\r
+\r
+ function getClass(){\r
+ $str = 'GD Wrapper';\r
+ if($this->isWorking()){\r
+ $a = gd_info(); $str .= ' : '.$a['GD Version'];\r
+ }\r
+ return $str;\r
+ }\r
+\r
+ function isWorking(){\r
+ return extension_loaded('gd') && function_exists('ImageCreateTrueColor') && function_exists('ImageCopyResampled');\r
+ }\r
+\r
+ function setThumbnailConfig($thumbWidth, $thumbHeight, $thumbQuality=50){\r
+ $this->thumbWidth = $thumbWidth;\r
+ $this->thumbHeight = $thumbHeight;\r
+ $this->thumbQuality = $thumbQuality;\r
+ }\r
+\r
+ function makeThumbnailtoFile($destFile){\r
+ if(!$this->isWorking()) return false;\r
+ switch(strtolower(strrchr($this->sourceFile, '.'))){ // 取出副檔名\r
+ case '.jpg':\r
+ $im_in = @ImageCreateFromJPEG($this->sourceFile); break;\r
+ case '.gif':\r
+ $im_in = @ImageCreateFromGIF($this->sourceFile); break;\r
+ case '.png':\r
+ $im_in = @ImageCreateFromPNG($this->sourceFile); break;\r
+ case '.rle':\r
+ case '.bmp':\r
+ $im_in = $this->_ImageCreateFromBMP($this->sourceFile); break;\r
+ default:\r
+ return false;\r
+ }\r
+ if(!$im_in) return false;\r
+ $im_out = ImageCreateTrueColor($this->thumbWidth, $this->thumbHeight);\r
+ ImageCopyResampled($im_out, $im_in, 0, 0, 0, 0, $this->thumbWidth, $this->thumbHeight, $this->sourceWidth, $this->sourceHeight);\r
+ ImageJPEG($im_out, $destFile, $this->thumbQuality);\r
+ ImageDestroy($im_in); ImageDestroy($im_out);\r
+ return true;\r
+ }\r
+}\r
+?>
\ No newline at end of file
--- /dev/null
+<?php\r
+/**\r
+ * Thumbnail Generate API: Imagick Wrapper\r
+ *\r
+ * 提供程式便於以 Imagick (Imagick Image Library) 生成預覽圖的物件\r
+ *\r
+ * @package PMCLibrary\r
+ * @version $Id: thumb.imagick.php 490 2007-07-26 14:36:47Z scribe $\r
+ * @date $Date: 2007-07-26 22:36:47 +0800 (星期四, 26 七月 2007) $\r
+ */\r
+\r
+class ThumbWrapper{\r
+ var $sourceFile, $sourceWidth, $sourceHeight, $thumbWidth, $thumbHeight, $thumbQuality;\r
+\r
+ function ThumbWrapper($sourceFile='', $sourceWidth=0, $sourceHeight=0){\r
+ $this->sourceFile = $sourceFile;\r
+ $this->sourceWidth = $sourceWidth;\r
+ $this->sourceHeight = $sourceHeight;\r
+ }\r
+\r
+ function getClass(){\r
+ $str = 'Imagick Wrapper';\r
+ if($this->isWorking()){\r
+ $a = new Imagick(); $b = $a->getVersion(); $b = $b['versionString'];\r
+ $str .= ' : '.str_replace(strrchr($b, ' '), '', $b);\r
+ unset($a); unset($b);\r
+ }\r
+ return $str;\r
+ }\r
+\r
+ function isWorking(){\r
+ return extension_loaded('imagick') && class_exists('Imagick');\r
+ }\r
+\r
+ function setThumbnailConfig($thumbWidth, $thumbHeight, $thumbQuality=50){\r
+ $this->thumbWidth = $thumbWidth;\r
+ $this->thumbHeight = $thumbHeight;\r
+ $this->thumbQuality = $thumbQuality;\r
+ }\r
+\r
+ function makeThumbnailtoFile($destFile){\r
+ $returnVal = false;\r
+ if(!$this->isWorking()) return false;\r
+ $image = new Imagick($this->sourceFile);\r
+ $image->setCompressionQuality($this->thumbQuality);\r
+ $image->thumbnailImage($this->thumbWidth, $this->thumbHeight);\r
+ $returnVal = $image->writeImage($destFile);\r
+ unset($image);\r
+ return $returnVal;\r
+ }\r
+}\r
+?>
\ No newline at end of file
--- /dev/null
+<?php\r
+/**\r
+ * Thumbnail Generate API: MagickWand Wrapper\r
+ *\r
+ * 提供程式便於以 MagickWand for PHP 生成預覽圖的物件\r
+ *\r
+ * @package PMCLibrary\r
+ * @version $Id: thumb.magickwand.php 490 2007-07-26 14:36:47Z scribe $\r
+ * @date $Date: 2007-07-26 22:36:47 +0800 (星期四, 26 七月 2007) $\r
+ */\r
+\r
+class ThumbWrapper{\r
+ var $sourceFile, $sourceWidth, $sourceHeight, $thumbWidth, $thumbHeight, $thumbQuality;\r
+\r
+ function ThumbWrapper($sourceFile='', $sourceWidth=0, $sourceHeight=0){\r
+ $this->sourceFile = $sourceFile;\r
+ $this->sourceWidth = $sourceWidth;\r
+ $this->sourceHeight = $sourceHeight;\r
+ }\r
+\r
+ function getClass(){\r
+ $str = 'MagickWand Wrapper';\r
+ if($this->isWorking()){\r
+ $a = MagickGetVersion(); $b = $a[0];\r
+ $str .= ' : '.str_replace(strrchr($b, ' '), '', $b);\r
+ unset($a); unset($b);\r
+ }\r
+ return $str;\r
+ }\r
+\r
+ function isWorking(){\r
+ return extension_loaded('magickwand') && function_exists('MagickThumbnailImage');\r
+ }\r
+\r
+ function setThumbnailConfig($thumbWidth, $thumbHeight, $thumbQuality=50){\r
+ $this->thumbWidth = $thumbWidth;\r
+ $this->thumbHeight = $thumbHeight;\r
+ $this->thumbQuality = $thumbQuality;\r
+ }\r
+\r
+ function makeThumbnailtoFile($destFile){\r
+ $returnVal = false;\r
+ if(!$this->isWorking()) return false;\r
+ $image = NewMagickWand();\r
+ MagickReadImage($image, $this->sourceFile);\r
+ MagickSetImageCompressionQuality($image, $this->thumbQuality);\r
+ MagickThumbnailImage($image, $this->thumbWidth, $this->thumbHeight);\r
+ $returnVal = MagickWriteImage($image, $destFile);\r
+ unset($image);\r
+ return $returnVal;\r
+ }\r
+}\r
+?>
\ No newline at end of file