PHP图片拼接类
支持横向和纵向的图片拼接,可以选择将拼接好的图片输出到文件或输出到用户浏览器,并且可以设置允许的最大宽度或最大高度,程序将自动进行缩放。
值得注意的是,程序中包含了一个重写了的file_get_contents
函数。phper都知道,普通的file_get_contents
是fsockopen
功能的简单打包,如果网速很慢或下载这个页面需要很长的时间,会卡在那,持续占用资源,具体分析可以看张宴 - PHP-CGI 进程 CPU 100% 与 file_get_contents 函数的关系。所以此处的file_get_contents
重写了一下,避免出现上述情况。
<?php /** * Created by IntelliJ IDEA. * User: chenzhidong * Date: 13-11-19 * Time: 下午2:55 */ class ImageCombiner { const COMBINE_HORIZONTAL = 1; const COMBINE_VERTICAL = 2; private $srcs; private $src_infos; private $dest_type = IMAGETYPE_JPEG; private $dest_width = 0; private $dest_height = 0; private $combine_mode = self::COMBINE_VERTICAL; private $canvas; private $done = false; public function __construct($srcs, $mode = self::COMBINE_VERTICAL, $dest_width = 0, $dest_height = 0) { $this->srcs = $srcs; $this->combine_mode = $mode; $this->dest_width = $dest_width; $this->dest_height = $dest_height; $this->canvas = null; } private function sys_get_temp_dir() { if (function_exists('sys_get_temp_dir')) { return sys_get_temp_dir(); } if ($temp = getenv('TMP')) { return $temp; } if ($temp = getenv('TEMP')) { return $temp; } if ($temp = getenv('TMPDIR')) { return $temp; } $temp = tempnam(__FILE__, ''); if (file_exists($temp)) { unlink($temp); return dirname($temp); } return null; } private function file_get_contents($url, $use_include_path = false, $stream_context = null, $curl_timeout = 8) { if ($stream_context == null && preg_match('/^https?:\/\//', $url)) $stream_context = @stream_context_create(array('http' => array('timeout' => $curl_timeout))); if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1')) || !preg_match('/^https?:\/\//', $url)) return @file_get_contents($url, $use_include_path, $stream_context); elseif (function_exists('curl_init')) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($curl, CURLOPT_TIMEOUT, $curl_timeout); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); $opts = stream_context_get_options($stream_context); if (isset($opts['http']['method']) && strtolower($opts['http']['method']) == 'post') { curl_setopt($curl, CURLOPT_POST, true); if (isset($opts['http']['content'])) { parse_str($opts['http']['content'], $datas); curl_setopt($curl, CURLOPT_POSTFIELDS, $datas); } } $content = curl_exec($curl); curl_close($curl); return $content; } else return false; } private function saveFile($url, $filepath) { if ($url && $filepath) { $file = $this->file_get_contents($url); $fp = @fopen($filepath, 'w'); if ($fp) { @fwrite($fp, $file); @fclose($fp); return $filepath; } } return false; } private function writeImage($type, $resource, $filename) { switch ($type) { case IMAGETYPE_GIF: $success = imagegif($resource, $filename); break; case IMAGETYPE_PNG: $success = imagepng($resource, $filename); break; case IMAGETYPE_BMP: $success = imagewbmp($resource, $filename); break; case IMAGETYPE_JPEG: default: $success = imagejpeg($resource, $filename, 100); break; } @chmod($filename, 0664); return $success; } private function checkSrcs() { foreach ($this->srcs as $key => $src) { $tmp = tempnam($this->sys_get_temp_dir(), 'img_'); if ($this->saveFile($src, $tmp)) { list($src_width, $src_height, $type) = @getimagesize($tmp); if ($src_width && $src_height && $type && in_array($type, array(IMAGETYPE_BMP, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_GIF))) { $image = array('width' => $src_width, 'height' => $src_height, 'type' => $type, 'image' => $tmp); $this->src_infos[$key] = $image; } else { unset($this->srcs[$key]); } } else { unset($this->srcs[$key]); } } } private function checkSizes() { switch ($this->combine_mode) { case self::COMBINE_VERTICAL: if (!$this->dest_width) { foreach ($this->src_infos as $src) { $this->dest_width = max($this->dest_width, $src['width']); } } foreach ($this->src_infos as $src) { $this->dest_height += round($this->dest_width * $src['height'] / $src['width']); } break; case self::COMBINE_HORIZONTAL: if (!$this->dest_height) { foreach ($this->src_infos as $src) { $this->dest_height = max($this->dest_height, $src['height']); } } foreach ($this->src_infos as $src) { $this->dest_width += round($this->dest_height * $src['width'] / $src['height']); } break; } } private function createTransImage($width, $height) { $image = imagecreatetruecolor($width, $height); $white = imagecolorallocate($image, 255, 255, 255); imagefill($image, 0, 0, $white); imagecolortransparent($image, $white); return $image; } private function combineVertical() { $destX = 0; $destY = 0; foreach ($this->src_infos as $key => $src) { if ($this->dest_width != $src['width']) { $dest_height = round($src['height'] * ($this->dest_width / $src['width'])); } else $dest_height = $src['height']; switch ($src['type']) { case IMAGETYPE_PNG: $image = @imagecreatefrompng($src['image']); break; case IMAGETYPE_BMP: $image = @imagecreatefromwbmp($src['image']); break; case IMAGETYPE_GIF: $image = @imagecreatefromgif($src['image']); break; case IMAGETYPE_JPEG: default: $image = @imagecreatefromjpeg($src['image']); break; } if ($image && !imagecopyresampled($this->canvas, $image, $destX, $destY, 0, 0, $this->dest_width, $dest_height, $src['width'], $src['height'])) return false; if ($image) imagedestroy($image); unlink($src['image']); $destY += $dest_height; } return $this->canvas; } private function combineHorizontal() { $destX = 0; $destY = 0; foreach ($this->src_infos as $key => $src) { if ($this->dest_height != $src['height']) { $dest_width = round($src['width'] * ($this->dest_height / $src['height'])); } else $dest_width = $src['width']; switch ($src['type']) { case IMAGETYPE_PNG: $image = @imagecreatefrompng($src['image']); break; case IMAGETYPE_BMP: $image = @imagecreatefromwbmp($src['image']); break; case IMAGETYPE_GIF: $image = @imagecreatefromgif($src['image']); break; case IMAGETYPE_JPEG: default: $image = @imagecreatefromjpeg($src['image']); break; } if ($image && !imagecopyresampled($this->canvas, $image, $destX, $destY, 0, 0, $dest_width, $this->dest_height, $src['width'], $src['height'])) return false; if ($image) imagedestroy($image); unlink($src['image']); $destX += $dest_width; } return true; } public function setDestType($type) { $this->dest_type = $type; } public function getDestType() { return $this->dest_type; } private function combine() { if (!$this->done) { if (PHP_VERSION_ID < 50300) clearstatcache(); $this->checkSrcs(); $this->checkSizes(); if (!empty($this->src_infos)) { $this->canvas = $this->createTransImage($this->dest_width, $this->dest_height); switch ($this->combine_mode) { case self::COMBINE_HORIZONTAL: $this->done = $this->combineHorizontal(); break; case self::COMBINE_VERTICAL: $this->done = $this->combineVertical(); break; } } } return $this->done; } public function getCombination() { $image = $this->combine(); if ($image) return $this->canvas; return false; } public function showCombination() { $image = $this->combine(); if ($image) { switch ($this->getDestType()) { case IMAGETYPE_GIF: header("Content-type: image/gif"); imagegif($this->canvas); break; case IMAGETYPE_BMP: header("Content-type: image/bmp"); imagewbmp($this->canvas); break; case IMAGETYPE_JPEG: header("Content-type: image/jpeg"); imagejpeg($this->canvas); break; case IMAGETYPE_PNG: header("Content-type: image/png"); imagepng($this->canvas); break; } } imagedestroy($this->canvas); } public function saveCombination($dest_file) { $image = $this->combine(); if ($image) { if ($this->writeImage($this->dest_type, $this->canvas, $dest_file)) { imagedestroy($this->canvas); return true; } } return false; } }
相关文章
上一篇: 完整的微信接口类下一篇: 网上的将汉字转换为拼音的类