123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- <?php
- //error_reporting(E_ALL & ~E_NOTICE);
- //ini_set("display_errors", 1);
- ini_set('memory_limit', '-1');
- class ImagickUtils
- {
- /**
- * @var Imagick
- */
- private $image = null;
- private $type = null;
- /**
- * 构造函数
- *
- * ImagickUtils constructor.
- */
- public function __construct()
- {
- }
- /**
- * 析构函数
- */
- public function __destruct()
- {
- if ($this->image !== null) $this->image->destroy();
- }
- /**
- * 载入图像
- * @param $path
- * @return Imagick|null
- * @throws \ImagickException
- */
- public function open($path)
- {
- $this->image = new Imagick($path);
- if ($this->image) {
- $this->type = strtolower($this->image->getImageFormat());
- }
- return $this->image;
- }
- /**
- * @return Imagick
- */
- public function getImage(){
- return $this->image;
- }
- /**
- * @param int $x
- * @param int $y
- * @param null $width
- * @param null $height
- * @throws \ImagickException
- */
- public function crop($x = 0, $y = 0, $width = null, $height = null)
- {
- if ($width == null) $width = $this->image->getImageWidth() - $x;
- if ($height == null) $height = $this->image->getImageHeight() - $y;
- if ($width <= 0 || $height <= 0) return;
- if ($this->type == 'gif') {
- $image = $this->image;
- $canvas = new Imagick();
- $images = $image->coalesceImages();
- foreach ($images as $frame) {
- $img = new Imagick();
- $img->readImageBlob($frame);
- $img->cropImage($width, $height, $x, $y);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- $canvas->setImagePage($width, $height, 0, 0);
- }
- $image->destroy();
- $this->image = $canvas;
- } else {
- $this->image->cropImage($width, $height, $x, $y);
- }
- }
- /*
- * 更改图像大小
- $fit: 适应大小方式
- 'force': 把图片强制变形成 $width X $height 大小
- 'scale': 按比例在安全框 $width X $height 内缩放图片, 输出缩放后图像大小 不完全等于 $width X $height
- 'scale_fill': 按比例在安全框 $width X $height 内缩放图片,安全框内没有像素的地方填充色, 使用此参数时可设置背景填充色 $bg_color = array(255,255,255)(红,绿,蓝, 透明度) 透明度(0不透明-127完全透明))
- 其它: 智能模能 缩放图像并载取图像的中间部分 $width X $height 像素大小
- $fit = 'force','scale','scale_fill' 时: 输出完整图像
- $fit = 图像方位值 时, 输出指定位置部分图像
- 字母与图像的对应关系如下:
- north_west north north_east
- west center east
- south_west south south_east
- */
- /**
- * @param int $width
- * @param int $height
- * @param string $fit
- * @param array $fill_color
- * @throws \ImagickException
- */
- public function resize_to($width = 100, $height = 100, $fit = 'center', $fill_color = array(255, 255, 255, 0))
- {
- switch ($fit) {
- case 'force':
- if ($this->type == 'gif') {
- $image = $this->image;
- $canvas = new Imagick();
- $images = $image->coalesceImages();
- foreach ($images as $frame) {
- $img = new Imagick();
- $img->readImageBlob($frame);
- $img->thumbnailImage($width, $height, false);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- }
- $image->destroy();
- $this->image = $canvas;
- } else {
- $this->image->thumbnailImage($width, $height, false);
- }
- break;
- case 'scale':
- if ($this->type == 'gif') {
- $image = $this->image;
- $images = $image->coalesceImages();
- $canvas = new Imagick();
- foreach ($images as $frame) {
- $img = new Imagick();
- $img->readImageBlob($frame);
- $img->thumbnailImage($width, $height, true);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- }
- $image->destroy();
- $this->image = $canvas;
- } else {
- $this->image->thumbnailImage($width, $height, true);
- }
- break;
- case 'scale_fill':
- $size = $this->image->getImagePage();
- $src_width = $size['width'];
- $src_height = $size['height'];
- $x = 0;
- $y = 0;
- $dst_width = $width;
- $dst_height = $height;
- if ($src_width * $height > $src_height * $width) {
- $dst_height = intval($width * $src_height / $src_width);
- $y = intval(($height - $dst_height) / 2);
- } else {
- $dst_width = intval($height * $src_width / $src_height);
- $x = intval(($width - $dst_width) / 2);
- }
- $image = $this->image;
- $canvas = new Imagick();
- $color = 'rgba(' . $fill_color[0] . ',' . $fill_color[1] . ',' . $fill_color[2] . ',' . $fill_color[3] . ')';
- if ($this->type == 'gif') {
- $images = $image->coalesceImages();
- foreach ($images as $frame) {
- $frame->thumbnailImage($width, $height, true);
- $draw = new ImagickDraw();
- $draw->composite($frame->getImageCompose(), $x, $y, $dst_width, $dst_height, $frame);
- $img = new Imagick();
- $img->newImage($width, $height, $color, 'gif');
- $img->drawImage($draw);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- $canvas->setImagePage($width, $height, 0, 0);
- }
- } else {
- $image->thumbnailImage($width, $height, true);
- $draw = new ImagickDraw();
- $draw->composite($image->getImageCompose(), $x, $y, $dst_width, $dst_height, $image);
- $canvas->newImage($width, $height, $color, $this->get_type());
- $canvas->drawImage($draw);
- $canvas->setImagePage($width, $height, 0, 0);
- }
- $image->destroy();
- $this->image = $canvas;
- break;
- default:
- $size = $this->image->getImagePage();
- $src_width = $size['width'];
- $src_height = $size['height'];
- // $crop_x = 0;
- // $crop_y = 0;
- $crop_w = $src_width;
- $crop_h = $src_height;
- if ($src_width * $height > $src_height * $width) {
- $crop_w = intval($src_height * $width / $height);
- } else {
- $crop_h = intval($src_width * $height / $width);
- }
- switch ($fit) {
- case 'north_west':
- $crop_x = 0;
- $crop_y = 0;
- break;
- case 'north':
- $crop_x = intval(($src_width - $crop_w) / 2);
- $crop_y = 0;
- break;
- case 'north_east':
- $crop_x = $src_width - $crop_w;
- $crop_y = 0;
- break;
- case 'west':
- $crop_x = 0;
- $crop_y = intval(($src_height - $crop_h) / 2);
- break;
- case 'center':
- $crop_x = intval(($src_width - $crop_w) / 2);
- $crop_y = intval(($src_height - $crop_h) / 2);
- break;
- case 'east':
- $crop_x = $src_width - $crop_w;
- $crop_y = intval(($src_height - $crop_h) / 2);
- break;
- case 'south_west':
- $crop_x = 0;
- $crop_y = $src_height - $crop_h;
- break;
- case 'south':
- $crop_x = intval(($src_width - $crop_w) / 2);
- $crop_y = $src_height - $crop_h;
- break;
- case 'south_east':
- $crop_x = $src_width - $crop_w;
- $crop_y = $src_height - $crop_h;
- break;
- default:
- $crop_x = intval(($src_width - $crop_w) / 2);
- $crop_y = intval(($src_height - $crop_h) / 2);
- }
- $image = $this->image;
- $canvas = new Imagick();
- if ($this->type == 'gif') {
- $images = $image->coalesceImages();
- foreach ($images as $frame) {
- $img = new Imagick();
- $img->readImageBlob($frame);
- $img->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
- $img->thumbnailImage($width, $height, true);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- $canvas->setImagePage($width, $height, 0, 0);
- }
- } else {
- $image->cropImage($crop_w, $crop_h, $crop_x, $crop_y);
- $image->thumbnailImage($width, $height, true);
- $canvas->addImage($image);
- $canvas->setImagePage($width, $height, 0, 0);
- }
- $image->destroy();
- $this->image = $canvas;
- }
- }
- // 添加水印图片
- /**
- * @param $path
- * @param int $x
- * @param int $y
- * @throws \ImagickException
- */
- public function add_watermark($path, $x = 0, $y = 0)
- {
- $watermark = new Imagick($path);
- $draw = new ImagickDraw();
- $draw->composite($watermark->getImageCompose(), $x, $y, $watermark->getImageWidth(), $watermark->getimageheight(), $watermark);
- if ($this->type == 'gif') {
- $image = $this->image;
- $canvas = new Imagick();
- // $images = $image->coalesceImages();
- foreach ($image as $frame) {
- $img = new Imagick();
- $img->readImageBlob($frame);
- $img->drawImage($draw);
- $canvas->addImage($img);
- $canvas->setImageDelay($img->getImageDelay());
- }
- $image->destroy();
- $this->image = $canvas;
- } else {
- $this->image->drawImage($draw);
- }
- }
- // 添加水印文字
- /**
- * @param $text
- * @param int $x
- * @param int $y
- * @param int $angle
- * @param array $style
- */
- public function add_text($text, $x = 0, $y = 0, $angle = 0, $style = array())
- {
- $draw = new ImagickDraw();
- if (isset($style['font'])) $draw->setFont($style['font']);
- if (isset($style['font_size'])) $draw->setFontSize($style['font_size']);
- if (isset($style['fill_color'])) $draw->setFillColor($style['fill_color']);
- if (isset($style['under_color'])) $draw->setTextUnderColor($style['under_color']);
- if ($this->type == 'gif') {
- foreach ($this->image as $frame) {
- $frame->annotateImage($draw, $x, $y, $angle, $text);
- }
- } else {
- $this->image->annotateImage($draw, $x, $y, $angle, $text);
- }
- }
- // 保存到指定路径
- /**
- * @param $path
- */
- public function save_to($path)
- {
- if ($this->type == 'gif') {
- $this->image->writeImages($path, true);
- } else {
- $this->image->writeImage($path);
- }
- }
- // 输出图像
- /**
- * @param bool $header
- * @throws \ImagickException
- */
- public function output($header = true)
- {
- if ($header) header('Content-type: ' . $this->type);
- echo $this->image->getImagesBlob();
- }
- /**
- * @return mixed
- */
- public function get_width()
- {
- $size = $this->image->getImagePage();
- return $size['width'];
- }
- /**
- * @return mixed
- */
- public function get_height()
- {
- $size = $this->image->getImagePage();
- return $size['height'];
- }
- // 设置图像类型, 默认与源类型一致
- /**
- * @param string $type
- */
- public function set_type($type = 'png')
- {
- $this->type = $type;
- $this->image->setImageFormat($type);
- }
- // 获取源图像类型
- /**
- * @return null
- */
- public function get_type()
- {
- return $this->type;
- }
- // 当前对象是否为图片
- /**
- * @return bool
- */
- public function is_image()
- {
- if ($this->image)
- return true;
- else
- return false;
- }
- /**
- * @param int $width
- * @param int $height
- * @param bool $fit
- */
- public function thumbnail($width = 100, $height = 100, $fit = true)
- {
- $this->image->thumbnailImage($width, $height, $fit);
- } // 生成缩略图 $fit为真时将保持比例并在安全框 $width X $height 内生成缩略图片
- /*
- 添加一个边框
- $width: 左右边框宽度
- $height: 上下边框宽度
- $color: 颜色: RGB 颜色 'rgb(255,0,0)' 或 16进制颜色 '#FF0000' 或颜色单词 'white'/'red'...
- */
- /**
- * @param $width
- * @param $height
- * @param string $color
- */
- public function border($width, $height, $color = 'rgb(220, 220, 220)')
- {
- $color = new ImagickPixel();
- $color->setColor($color);
- $this->image->borderImage($color, $width, $height);
- }
- /**
- * @param $radius
- * @param $sigma
- */
- public function blur($radius, $sigma)
- {
- $this->image->blurImage($radius, $sigma);
- } // 模糊
- /**
- * @param $radius
- * @param $sigma
- */
- public function gaussian_blur($radius, $sigma)
- {
- $this->image->gaussianBlurImage($radius, $sigma);
- } // 高斯模糊
- /**
- * @param $radius
- * @param $sigma
- * @param $angle
- */
- public function motion_blur($radius, $sigma, $angle)
- {
- $this->image->motionBlurImage($radius, $sigma, $angle);
- } // 运动模糊
- /**
- * @param $radius
- */
- public function radial_blur($radius)
- {
- $this->image->radialBlurImage($radius);
- } // 径向模糊
- /**
- * @param null $type
- */
- public function add_noise($type = null)
- {
- $this->image->addNoiseImage($type == null ? imagick::NOISE_IMPULSE : $type);
- } // 添加噪点
- /**
- * @param $black_point
- * @param $gamma
- * @param $white_point
- */
- public function level($black_point, $gamma, $white_point)
- {
- $this->image->levelImage($black_point, $gamma, $white_point);
- } // 调整色阶
- /**
- * @param $brightness
- * @param $saturation
- * @param $hue
- */
- public function modulate($brightness, $saturation, $hue)
- {
- $this->image->modulateImage($brightness, $saturation, $hue);
- } // 调整亮度、饱和度、色调
- /**
- * @param $radius
- * @param $sigma
- */
- public function charcoal($radius, $sigma)
- {
- $this->image->charcoalImage($radius, $sigma);
- } // 素描
- /**
- * @param $radius
- */
- public function oil_paint($radius)
- {
- $this->image->oilPaintImage($radius);
- } // 油画效果
- public function flop()
- {
- $this->image->flopImage();
- } // 水平翻转
- public function flip()
- {
- $this->image->flipImage();
- } // 垂直翻转
- }
- function caclSize($src, $width = null, $height = null)
- {
- if (!isset($width) && !isset($height))
- return false;
- if (isset($width) && $width <= 0)
- return false;
- if (isset($height) && $height <= 0)
- return false;
- $size = getimagesize($src);
- if (!$size)
- return false;
- list($src_w, $src_h, $src_type) = $size;
- if (!isset($width))
- $width = $src_w * ($height / $src_h);
- if (!isset($height)) {
- $height = $src_h * ($width / $src_w);
- }
- return [$width, $height];
- }
- /**
- * 生成缩略图函数(支持图片格式:gif、jpeg、png和bmp)
- * @author ruxing.li
- * @param string $src 源图片路径
- * @param int $width 缩略图宽度(只指定高度时进行等比缩放)
- * @param int $height 缩略图高度(只指定宽度时进行等比缩放)
- * @param string $filename 保存路径(不指定时直接输出到浏览器)
- * @return bool
- */
- function mkThumbnail($src, $width = null, $height = null, $filename = null)
- {
- if (!isset($width) && !isset($height))
- return false;
- if (isset($width) && $width <= 0)
- return false;
- if (isset($height) && $height <= 0)
- return false;
- $size = getimagesize($src);
- if (!$size)
- return false;
- list($src_w, $src_h, $src_type) = $size;
- $src_mime = $size['mime'];
- switch ($src_type) {
- case 1 :
- $img_type = 'gif';
- break;
- case 2 :
- $img_type = 'jpeg';
- break;
- case 3 :
- $img_type = 'png';
- break;
- case 15 :
- $img_type = 'wbmp';
- break;
- default :
- return false;
- }
- $exif=[];
- try{
- if ($src_type==2&&function_exists('exif_read_data')) {
- $exif = exif_read_data($src);
- }
- }catch (\Exception $e){
- }
- $imagecreatefunc = 'imagecreatefrom' . $img_type;
- $src_img = $imagecreatefunc($src);
- if (isset($exif['Orientation']) && !empty($exif['Orientation'])) {
- switch ($exif['Orientation']) {
- case 8:
- $src_img = imagerotate($src_img, 90, 255);
- $tmp = $src_w;
- $src_w = $src_h;
- $src_h = $tmp;
- break;
- case 3:
- $src_img = imagerotate($src_img, 180, 255);
- break;
- case 6:
- $src_img = imagerotate($src_img, -90, 255);
- $tmp = $src_w;
- $src_w = $src_h;
- $src_h = $tmp;
- break;
- }
- }
- if (!isset($width))
- $width = $src_w * ($height / $src_h);
- if (!isset($height)) {
- $height = $src_h * ($width / $src_w);
- }
- $dest_img = imagecreatetruecolor($width, $height);
- $imagefunc = 'image' . $img_type;
- imagesavealpha($src_img, true);//这里很重要 意思是不要丢了$sourePic图像的透明色;
- imagealphablending($dest_img, false);//这里很重要,意思是不合并颜色,直接用$img图像颜色替换,包括透明色;
- imagesavealpha($dest_img, true);//这里很重要,意思是不要丢了$thumb图像的透明色;
- if (imagecopyresampled($dest_img, $src_img, 0, 0, 0, 0, $width, $height, $src_w, $src_h)) {
- header('Content-Type: ' . $src_mime);
- $imagefunc($dest_img);
- }
- imagedestroy($src_img);
- imagedestroy($dest_img);
- }
- function run()
- {
- if(!isset($_GET['file'])){
- $file = '/blank.png';
- }else{
- $file = $_GET['file'];
- }
- $filePath = "." . $file;
- if (!file_exists($filePath)) {
- $filePath = './files/blank.png';
- }
- if(!isset($_GET['x-oss-process'])){
- header('Content-Type: image/jpeg');
- readfile($filePath);
- exit();
- }else{
- $param = $_GET['x-oss-process'];
- }
- $width = null;
- $height = null;
- //此处style名称与阿里云的对应,已经添加几个内置样式,TODO 增加阿里云的处理规则https://help.aliyun.com/document_detail/44687.html?spm=5176.doc44695.6.945.5m3Qxo
- if ((preg_match('/style\/(\d+)([w|h])+/', $param, $match))) {
- if ($match[2] == 'w') {
- $width = $match[1];
- }
- if ($match[2] == 'h') {
- $height = $match[1];
- }
- } else {
- throw new \Exception('x-oss-process参数格式错误');
- }
- if (extension_loaded('imagick')) {
- list($width, $height) = caclSize($filePath, $width, $height);
- $object = new ImagickUtils();
- $object->open($filePath);
- $dirDegree = intval($object->getImage()->getImageProperty("exif:Orientation"));
- switch ($dirDegree) {
- case \Imagick::ORIENTATION_LEFTBOTTOM:
- $object->getImage()->rotateImage(new ImagickPixel(), -90);
- $tmp = $width;
- $width = $height;
- $height = $tmp;
- break;
- case \Imagick::ORIENTATION_BOTTOMRIGHT:
- $object->getImage()->rotateImage(new ImagickPixel(), 180);
- break;
- case \Imagick::ORIENTATION_RIGHTTOP:
- $object->getImage()->rotateImage(new ImagickPixel(), 90);
- $tmp = $width;
- $width = $height;
- $height = $tmp;
- break;
- }
- $object->resize_to($width, $height);
- $object->output();
- //return;
- } else {
- mkThumbnail($filePath, $width, $height);
- }
- exit();
- }
- //var_dump($_GET);
- run();
|