PHP圖像處理雖然不比其他語言性能高,但應(yīng)付日常來說業(yè)務(wù)來說是夠用的衣摩。本類大部分是自己編寫其他則參考來自PHP手冊的代碼昂验。另外,要想正確使用記得要啟用GD庫艾扮。
簡單的使用像這樣:
$src= '/path/IMAGE_NAME.jpg';
$img = new UImage($src);
$path = $img->negate(); // 顏色翻轉(zhuǎn)
$path = $img->compress(); // 圖像壓縮
// 第二個參數(shù)如果啟用的話將會覆蓋原圖, 其他操作一樣
$img = new UImage($src, true);
注意的是處理后的圖像并不會覆蓋源文件既琴,重命名的部分可以自行調(diào)整代碼
<?php
/**
* YCZ - UImage
* present by YCZ
* Author: Nomandia
* Date: 2019/7/31 10:40
*/
class UImage
{
/**
* @var int 圖片寬
*/
public $width = 0;
/**
* @var int 圖片高
*/
public $height = 0;
/**
* @var int 圖片類型
*/
public $type;
/**
* @var string 圖片擴展名
*/
public $extension;
/**
* @var string 圖片MimeType
*/
public $mimeType;
/**
* @var array 圖片屬性
*/
public $attr;
/**
* @var string 原始圖像地址
*/
public $src;
/**
* @var string 創(chuàng)建臨時圖像的方法
*/
public $createfunc;
/**
* @var string 輸出圖像的方法
*/
public $exportfunc;
/**
* @var bool 是否處理后覆蓋原圖
*/
public $cover = false;
/**
* @var string 輸出路徑
*/
public $exportPath;
/**
* UImage constructor.
* @param string $src
* @param bool $cover
* @return $this
*/
function __construct($src = null, $cover = false)
{
$this->setSrc($src);
$this->cover = $cover;
return $this;
}
/**
* @param string $src
* @return $this|bool
* Author: Great Nomandia
* Created At 2019/7/31 12:16
*/
function setSrc($src)
{
if (!$src || !is_file($src) || !getimagesize($src)) {
return false;
}
// getimagesize 獲取圖像的基礎(chǔ)信息
list($this->width, $this->height, $this->type, $this->attr) = getimagesize($this->src = $src);
$this->extension = image_type_to_extension($this->type, false);
$this->mimeType = image_type_to_mime_type($this->type);
// 這里根據(jù)擴展名獲取相應(yīng)的處理方法
$this->createfunc = 'imagecreatefrom' . $this->extension;
if (!function_exists($this->createfunc)) {
Yii::error($this->exportfunc . ' not exists', 'api.uimage.createfunc');
return false;
}
$this->exportfunc = 'image' . $this->extension;
if (!function_exists($this->exportfunc)) {
Yii::error($this->exportfunc . ' not exists', 'api.uimage.exportfunc');
return false;
}
return $this;
}
/**
* 輸出路徑
* @param string $exportPath
* @param string $suffix
* @return string
* Author: Great Nomandia
* Created At 2019/7/31 18:07
*/
protected function getExportPath($exportPath = null, $suffix = null)
{
// 指定了輸出路徑直接返回
if ($exportPath) {
return $exportPath;
}
if ($this->cover) {
// 覆蓋時返回源文件路徑
return $this->src;
}
$pathinfo = pathinfo($this->src);
return $this->exportPath = $pathinfo['dirname'] . DIRECTORY_SEPARATOR . $pathinfo['filename'] . $suffix . '.' . $this->extension;
}
/**
* 翻轉(zhuǎn)圖
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:15
*/
function negate($exportPath = null)
{
return $this->process(IMG_FILTER_NEGATE, $exportPath);
}
/**
* 灰度圖
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:24
*/
function grayscale($exportPath = null)
{
return $this->process(IMG_FILTER_GRAYSCALE, $exportPath);
}
/**
* 邊界圖
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:24
*/
function edgedetect($exportPath = null)
{
return $this->process(IMG_FILTER_EDGEDETECT, $exportPath);
}
/**
* 浮雕圖
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:24
*/
function emboss($exportPath = null)
{
return $this->process(IMG_FILTER_EMBOSS, $exportPath);
}
/**
* 高斯模糊
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:43
*/
function gaussianblur($exportPath = null)
{
return $this->process(IMG_FILTER_GAUSSIAN_BLUR, $exportPath);
}
/**
* 嚴選
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:24
*/
function selective($exportPath = null)
{
return $this->process(IMG_FILTER_SELECTIVE_BLUR, $exportPath);
}
/**
* 輪廓圖
* @param string $exportPath
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:23
*/
function meanremoval($exportPath = null)
{
return $this->process(IMG_FILTER_MEAN_REMOVAL, $exportPath);
}
/**
* 亮度
* @param string $exportPath
* @param int $level 0-100
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:23
*/
function brightness($exportPath = null, $level = 50)
{
return $this->process(IMG_FILTER_BRIGHTNESS, $exportPath, $level);
}
/**
* 對比度
* @param string $exportPath
* @param int $level 0-100 越高顏色越少
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:23
*/
function contrast($exportPath = null, $level = 30)
{
return $this->process(IMG_FILTER_CONTRAST, $exportPath, $level);
}
/**
* 柔化
* @param string $exportPath
* @param int $level
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:23
*/
function smooth($exportPath = null, $level = 3)
{
return $this->process(IMG_FILTER_SMOOTH, $exportPath, $level);
}
/**
* 彩色灰度圖
* @param string $exportPath
* @param int $red
* @param int $blue
* @param int $green
* @return bool|UImage
* Author: Great Nomandia
* Created At 2019/7/31 15:21
*/
function colorize($exportPath = null, $red = 255, $blue = 0, $green = 0)
{
return $this->process(IMG_FILTER_COLORIZE, $exportPath, $red, $blue, $green);
}
/**
* @param string $mark_src
* @param int $x
* @param int $y
* @return $this
* Author: Great Nomandia
* Created At 2019/7/31 18:13
*/
function watermark($mark_src, $x, $y)
{
$image = call_user_func($this->createfunc, $this->src);
list($w, $h, $type, $attr) = getimagesize($mark_src);
$extension = image_type_to_extension($type, false);
// 加載水印圖
$marker = call_user_func('imagecreatefrom' . $extension, $mark_src);
imagecopy($image, $marker, $x, $y, 0, 0, $this->width, $this->height);
// 注意這里會覆蓋原圖
call_user_func($this->exportfunc, $image, $this->getExportPath($this->src, 'WM'));
imagedestroy($image);
imagedestroy($marker);
return $this;
}
/**
* 圖片旋轉(zhuǎn)
* @param int $angle 旋轉(zhuǎn)角度(正數(shù)為逆時針旋轉(zhuǎn) 負數(shù)為順時針)
* @param int $bgd_color 背景顏色
* @return $this|UImage
* Author: Great Nomandia
* Created At 2019/7/31 17:14
*/
function rotate($angle, $bgd_color = 0, $exportPath = null)
{
$image = call_user_func($this->createfunc, $this->src);
$image = imagerotate($image, $angle, $bgd_color);
call_user_func($this->exportfunc, $image, $this->getExportPath($exportPath, '.R'));
imagedestroy($image);
return $this;
}
/**
* X軸翻轉(zhuǎn) 垂直翻轉(zhuǎn)
* @param string $exportPath
* @return UImage
* Author: Great Nomandia
* Created At 2019/7/31 18:35
*/
function flipX($exportPath = null)
{
return $this->flip(IMG_FLIP_VERTICAL, $exportPath);
}
/**
* Y軸翻轉(zhuǎn) 水平翻轉(zhuǎn)
* @param string $exportPath
* @return mixed
* Author: Great Nomandia
* Created At 2019/7/31 18:34
*/
function flipY($exportPath = null)
{
return $this->flip(IMG_FLIP_HORIZONTAL, $exportPath);
}
/**
* 雙向翻轉(zhuǎn)
* @param string $exportPath
* @return UImage
* Author: Great Nomandia
* Created At 2019/7/31 18:34
*/
function flipBoth($exportPath = null)
{
return $this->flip(IMG_FLIP_BOTH, $exportPath);
}
/**
* @param int $mode
* @param string $exportPath
* @return $this|UImage
* Author: Great Nomandia
* Created At 2019/7/31 17:23
*/
function flip($mode = IMG_FLIP_HORIZONTAL, $exportPath = null)
{
$image = call_user_func($this->createfunc, $this->src);
imageflip($image, $mode);
call_user_func($this->exportfunc, $image, $this->getExportPath($exportPath, '.F'));
imagedestroy($image);
return $this;
}
/**
* 裁剪圖像
* @param int $dst_x
* @param int $dst_y
* @param int $width
* @param int $height
* @param int $quality
* @param bool $no_blank 無留空,即當裁切區(qū)域不足以填充新圖時也會留空白, true則不會但寬高會被裁剪
* @param null $exportPath
* @return string|null
* Author: Great Nomandia
* Created At 2019/7/31 16:51
*/
function cut($dst_x, $dst_y, $width, $height, $quality = 80, $no_blank = false, $exportPath = null)
{
if ($no_blank) {
$width = $this->width - $dst_x > $width ? $width : $this->width - $dst_x;
$height = $this->height - $dst_y > $height ? $height : $this->height - $dst_y;
}
return $this->copy($exportPath, 0, 0, $dst_x, $dst_y, $width, $height, $width, $height, $quality);
}
/**
* 等比縮放
* @param int $scale
* @param int $quality
* @param string $exportPath
* @return string|null
* Author: Great Nomandia
* Created At 2019/7/31 16:42
*/
function scale($scale = 1.0, $quality = 80, $exportPath = null)
{
return $this->copy($exportPath, 0, 0, 0, 0, $this->width * $scale, $this->height * $scale, null, null, $quality);
}
/**
* 重置大小
* @param int $width
* @param int $height
* @param int $quality
* @param string $exportPath
* @return string|null
* Author: Great Nomandia
* Created At 2019/7/31 16:33
*/
function resize($width, $height, $quality = 80, $exportPath = null)
{
return $this->copy($exportPath, 0, 0, 0, 0, $width, $height, null, null, $quality);
}
/**
* 復制圖像
* @param string $exportPath
* @param int $dst_x
* @param int $dst_y
* @param int $src_x
* @param int $src_y
* @param int $dst_width
* @param int $dst_height
* @param int $quality
* @return string|null
* Author: Great Nomandia
* Created At 2019/7/31 16:32
*/
function copy($exportPath = null, $dst_x = 0, $dst_y = 0, $src_x = 0, $src_y = 0, $dst_width = null, $dst_height = null, $src_width = null, $src_height = null, $quality = 70)
{
$image = call_user_func($this->createfunc, $this->src);
$dst_width = $dst_width ?: $this->width;
$dst_height = $dst_height ?: $this->height;
$src_width = $src_width ?: $this->width;
$src_height = $src_height ?: $this->height;
$thump = function_exists('imagecreatetruecolor') ?
imagecreatetruecolor($dst_width, $dst_height) :
imagecreate($dst_width, $dst_height);
// 注意如果縱橫比改變了那圖像將被拉伸
imagecopyresampled($thump, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_width, $dst_height, $src_width, $src_height);
call_user_func($this->exportfunc, $thump, $this->getExportPath($exportPath, $dst_width . 'x' . $dst_height), $quality);
imagedestroy($image);
imagedestroy($thump);
return $exportPath;
}
/**
* 處理圖片
* @param int $filter
* @param string $exportPath
* @return $this|bool
* Author: Great Nomandia
* Created At 2019/7/31 14:59
*/
function process($filter, $exportPath = null)
{
if (null === $filter) {
return false;
}
$image = call_user_func($this->createfunc, $this->src);
switch ($filter) {
case IMG_FILTER_NEGATE: // 0. 顏色翻轉(zhuǎn)
case IMG_FILTER_GRAYSCALE: // 1. 灰度圖
case IMG_FILTER_EDGEDETECT: // 5. 邊緣圖
case IMG_FILTER_EMBOSS: // 6. 浮雕圖
case IMG_FILTER_GAUSSIAN_BLUR: // 7. 高斯模糊
case IMG_FILTER_SELECTIVE_BLUR: // 8. 別樣模糊
case IMG_FILTER_MEAN_REMOVAL : // 9. 輪廓圖
imagefilter($image, $filter);
break;
case IMG_FILTER_BRIGHTNESS: // 2. 亮度調(diào)節(jié)
case IMG_FILTER_CONTRAST: // 3. 對比度
imagefilter($image, $filter, func_get_arg(2));
break;
case IMG_FILTER_SMOOTH: // 10. 柔化
imagefilter($image, $filter, func_get_arg(2));
break;
case IMG_FILTER_COLORIZE: // 4. 指定顏色的灰度圖泡嘴, 參數(shù)1=R 2=B 3=G, 值范圍0-255
imagefilter($image, $filter, func_get_arg(2), func_get_arg(3), func_get_arg(4));
break;
default:
// 非有效圖像不做處理
imagedestroy($image);
return $this;
}
call_user_func($this->exportfunc, $image, $this->getExportPath($exportPath, '.' . $filter));
imagedestroy($image);
return $this;
}
/**
* 模糊處理
* @param string $exportPath 輸出路徑(含文件名)
* @param int $factor
* @return $this|bool
* Author: Great Nomandia
* Created At 2019/7/31 14:37
*/
function blur($exportPath = null, $factor = 3)
{
if (!$this->createfunc) {
return false;
}
$image = call_user_func($this->createfunc, $this->src);
$factor = round($factor);
$originalWidth = imagesx($image);
$originalHeight = imagesy($image);
$smallestWidth = ceil($originalWidth * pow(0.5, $factor));
$smallestHeight = ceil($originalHeight * pow(0.5, $factor));
// for the first run, the previous image is the original input
$prevImage = $image;
$prevWidth = $originalWidth;
$prevHeight = $originalHeight;
// scale way down and gradually scale back up, blurring all the way
for ($i = 0; $i < $factor; $i++) {
// determine dimensions of next image
$nextWidth = $smallestWidth * pow(2, $i);
$nextHeight = $smallestHeight * pow(2, $i);
// resize previous image to next size
$nextImage = imagecreatetruecolor($nextWidth, $nextHeight);
imagecopyresized($nextImage, $prevImage, 0, 0, 0, 0, $nextWidth, $nextHeight, $prevWidth, $prevHeight);
// apply blur filter
imagefilter($nextImage, IMG_FILTER_GAUSSIAN_BLUR);
// now the new image becomes the previous image for the next step
$prevImage = $nextImage;
$prevWidth = $nextWidth;
$prevHeight = $nextHeight;
}
// scale back to original size and blur one more time
imagecopyresized($image, $nextImage, 0, 0, 0, 0, $originalWidth, $originalHeight, $nextWidth, $nextHeight);
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
// clean up
imagedestroy($prevImage);
call_user_func($this->exportfunc, $image, $this->getExportPath($exportPath, '.B' . $factor));
imagedestroy($image);
return $this;
}
/**
* 壓縮圖像
* @param float $ratio 保持原圖比例(等比縮放)
* @param int $quality 圖片質(zhì)量 0-100甫恩,越大越好
* @param string $exportPath 保存路徑 null 時將覆蓋源文件
* @return string
* Author: Great Nomandia
* Created At 2019/7/31 10:38
*/
function compress($ratio = 1.0, $quality = 60, $exportPath = null)
{
// 從SRC中創(chuàng)建一個圖像
if (!$this->createfunc) {
return false;
}
$image = call_user_func($this->createfunc, $this->src);
if (!$image) {
// 臨時圖創(chuàng)建失敗
return false;
}
// 臨時圖的寬高
$new_height = $this->height * $ratio;
$new_width = $this->width * $ratio;
// 創(chuàng)建臨時圖
if (function_exists('imagecreatetruecolor')) {
// 需要GD2支持,老版用imagecreate
$thump = imagecreatetruecolor($new_width, $new_height);
} else { // 此方法試過會失真
$thump = imagecreate($new_width, $new_height);
}
// 復制源圖像到臨時文件
imagecopyresampled($thump, $image, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
// 壓縮后的圖片的命名酌予,以及回存路徑
// IOS 圖片旋轉(zhuǎn)問題
// 1:0°,6:順時針90°, 8:逆時針90°,3:180°
if ((IMAGETYPE_JPEG == $this->type || IMAGETYPE_TIFF_II == $this->type)
&& function_exists('exif_read_data')) {
// JPEG 或 TIFF 文件中讀取 EXIF 頭信息, 這里自動處理旋轉(zhuǎn)的照片
$exif = exif_read_data($this->src);
if (isset($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 3:
$thump = imagerotate($thump, 180, 0);
break;
case 6:
$thump = imagerotate($thump, -90, 0);
break;
case 8:
$thump = imagerotate($thump, 90, 0);
break;
}
}
}
// 生成圖片, 注意quality并非所有方法都試用
// 另外 quality實測高于80時無效果磺箕,文件反而更大
call_user_func($this->exportfunc, $thump, $this->getExportPath($exportPath, '.C'), $quality);
// 銷毀
imagedestroy($thump);
imagedestroy($image);
return $this;
}
}