缩略图、旋转、截
缩略图、旋转、截取、水印、圆角
<?php
if(!function_exists("getimagesizefromstring")){
function getimagesizefromstring($str, array &$imageinfo = null){
$ret = false;
$tmpSrc = tempnam(sys_get_temp_dir(),"phpimage_");
if(file_put_contents($tmpSrc, $str)){
$ret = getimagesize($tmpSrc, $imageinfo);
unlink($tmpSrc);
}
return $ret;
}
}
/**
* <pre class="brush:php;toolbar:false">
* Img::get("face/2.jpg")->resize(200,200)->save()->destory();
* Img::get("face/2.jpg")->thumbnail(200,200)->save()->destory();
* Img::get("face/2.jpg")->corner()->save()->destory();
* Img::get("face/2.jpg")->cut(20,20,50,50)->save()->destory();
* Img::get("face/2.jpg")->rotate(45)->save()->destory();
* Img::get("face/2.jpg")->draw(Img::get("face/icon.png"), "BR")->save("face/2_logo.jpg")->destory();
*
Copy after login
* @author zhangheng
*/
class Img
{
protected $res;
protected $type = null;
protected $alphaed = false;
/**
* @return Img
*/
public static function get($src){
return new Img($src);
}
function __construct($src=false,$type=false)
{
if(is_string($src)){
if(file_exists($src)){
$info = getimagesize($src);
if($info){
if ($info[2] == IMAGETYPE_JPEG){
$this->res = imagecreatefromjpeg($src);
}else if($info[2] == IMAGETYPE_PNG){
$this->res = @imagecreatefrompng($src);
}else if($info[2] == IMAGETYPE_GIF){
$this->res = @imagecreatefromgif($src);
}else if($info[2] == IMAGETYPE_BMP){
$this->res = @imagecreatefromwbmp($src);
}
$this->type = self::typeStr($info[2]);
}
}else{
if(parse_url($src, PHP_URL_HOST)){
$src_ret = file_get_contents($src);
$info = getimagesizefromstring($src_ret);
if($info){
$this->res = @imagecreatefromstring($src_ret);
$this->type = self::typeStr($info[2]);
}
}else{
$this->res = @imagecreatefromstring($src);
}
}
}else if(is_array($src) && count($src)>1){
if(isset($src[0])){
$this->res = imagecreatetruecolor($src[0], $src[1]);
}else{
$this->res = imagecreatetruecolor($src["width"], $src["height"]);
}
}else if(is_resource($src)){
$this->res = $src;
if($type){
$this->type = $type;
}
}else if(get_class($src)==get_class($this)){
$this->res = $src->res;
$this->type = $src->type;
}
if(!$this->res){
throw new Exception("ArgumentError:".$src);
}
}
private function up($r){
@imagedestroy($this->res);
$this->res = $r;
}
/**
* 拉伸到目标大小
* @param int $width
* @param int $height
* @return Img
*/
public function resize($width, $height=false) {
$this->up(self::resizeImp($this->res, $width, $height, false, false));
return $this;
}
/**
* 生成目标大小缩略图(保持比例)
* @param int $width
* @param int $height
* @return Img
*/
public function thumbnail($width, $height=false){
$this->up(self::resizeImp($this->res, $width, $height, true, true));
return $this;
}
/**
* 限定最小一边-大小为$size, 并且保持比例
* @param int $size
*/
public function thumbByMin($size){
$w = $this->width();
$h = $this->height();
if($w==$h){
$w = $size;
$h = $size;
}else if($w>$h){
$w = $w/$h*$size;
$h = $size;
}else{
$h = $h/$w*$size;
$w = $size;
}
$this->up(self::resizeImp($this->res, $w, $h, false, false));
return $this;
}
/**
* 切图-到目标大小
* @param int $x
* @param int $y
* @param int $w
* @param int $h
* @return Img
*/
public function cut($x, $y, $width, $height){
$img = imagecreatetruecolor($width, $height);
imagealphablending($img, false);
imagesavealpha($img, true);
imagecopy($img, $this->res, 0, 0, $x, $y, $this->width(), $this->height());
imagedestroy($this->res);
$this->up($img);
return $this;
}
/**
* 将图片变成方形(默认以最小边为准)
* @param bool $small default-true
*/
public function square($small=TRUE){
$w = $this->width();
$h = $this->height();
if($w != $h){
$s = $small ? min(array($w,$h)) : max(array($w,$h));
$this->resize($s, $s);
}
return $this;
}
/**
* 方形剪切
* @param int $size 剪切后缩放到目标大小
* @return Img
*/
public function squareCut($size=false){
$w = $this->width();
$h = $this->height();
if($w != $h){
$s = min(array($w,$h));
$x = ($w-$s)/2;
$y = ($h-$s)/2;
$this->cut($x, $y, $s, $s);
}
if(is_int($size) && $size>0){
$this->resize($size);
}
return $this;
}
/**
* 制作圆角
* @param number $percent 圆角比例
* @param string $autoResize 自动调整尺寸(到方形)
* @param number $quality 图片质量
* @return Img
*/
public function corner($percent=1.0, $autoResize=false, $quality=4){
if($autoResize){
$this->square();
}
$w = $this->width();
$h = $this->height();
$src = $this->res;
$radius = min(array($w,$h))/2 * $percent;
$radius *= $quality;
$nw = $w*$quality;
$nh = $h*$quality;
$img = imagecreatetruecolor($nw, $nh);
// $alpha = imagecolorallocatealpha($img, 255, 255, 255, 127);
$alpha = self::makeColor($img, 0x7fffffff);
imagealphablending($img, false);
imagesavealpha($img, true);
imagefilledrectangle($img, 0, 0, $nw, $nh, $alpha);
imagefill($img, 0, 0, $alpha);
imagecopyresampled($img, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);
imagearc($img, $radius-1, $radius-1, $radius*2, $radius*2, 180, 270, $alpha);
imagefilltoborder($img, 0, 0, $alpha, $alpha);
imagearc($img, $nw-$radius, $radius-1, $radius*2, $radius*2, 270, 0, $alpha);
imagefilltoborder($img, $nw-1, 0, $alpha, $alpha);
imagearc($img, $radius-1, $nh-$radius, $radius*2, $radius*2, 90, 180, $alpha);
imagefilltoborder($img, 0, $nh-1, $alpha, $alpha);
imagearc($img, $nw-$radius, $nh-$radius, $radius*2, $radius*2, 0, 90, $alpha);
imagefilltoborder($img, $nw-1, $nh-1, $alpha, $alpha);
imagealphablending($img, true);
imagecolortransparent($img, $alpha);
# resize image down
$dest = imagecreatetruecolor($w, $h);
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagefilledrectangle($dest, 0, 0, $w, $h, $alpha);
imagecopyresampled($dest, $img, 0, 0, 0, 0, $w, $h, $nw, $nh);
imagedestroy($src);
imagedestroy($img);
$this->alphaed = true;
$this->up($dest);
return $this;
}
/**
* 图片旋转
* @param float $angle
* @param int $gdg_color
* @return Img
*/
public function rotate($angle, $gdg_color=0x7fffffff){
$this->up(imagerotate($this->res, $angle, $gdg_color));
imagealphablending($this->res, true);
imagesavealpha($this->res, true); $this->alphaed = true;
return $this;
}
/**
*
* @param string $fontfile
* @param string $text
* @param int $offsetX
* @param int $offsetY
* @param int $size
* @param int $angle
* @param real $color
* @param string $align
* @return Img
*/
public function write($fontfile, $text, $offsetX = 0, $offsetY = 0, $size = 14, $color = 0xff0000, $angle = 0, $align = 'BR'){
imagealphablending($this->res, true);
$box = imagettfbbox($size, $angle, $fontfile, $text);
$w = abs($box[2] - $box[0]);
$h = abs($box[3] - $box[5]);
if($h<$size){
$h = $size;
}
$x = 0;
$y = 0;
self::align($align, $x, $y, $w, $h, $this->width(), $this->height(), $offsetX, $offsetY);
//echo "$x,$y,$w,$h,".$this->width()."_".$this->height();exit();
imagettftext($this->res, $size, $angle, $x, $y+$h-3, self::makeColor($this->res, $color), $fontfile, $text);
return $this;
}
/**
* 绘制水印图片
* @param string $img
* @param string $align
* @param number $angle
* @param number $offsetX
* @param number $offsetY
* @param real $alpha
* @return Img
*/
public function draw($img, $align="BR", $angle=0, $offsetX=0, $offsetY=0, $alpha=1.0){
$img = new Img($img);
if($angle!=0){
$img->rotate($angle);
}
$w = $img->width();
$h = $img->height();
$x = 0;
$y = 0;
self::align($align, $x, $y, $w, $h, $this->width(), $this->height(), $offsetX, $offsetY);
imagealphablending($this->res, true);
imagecopy($this->res, $img->res, $x, $y, 0, 0, $w, $h);//拷贝水印到目标文件
return $this;
}
private static function align($align, &$x, &$y, $w, $h, $bw, $bh, $offsetX, $offsetY){
if($align=="BR"){
$x = ($bw-$w-$offsetX);
$y = ($bh-$h-$offsetY);
} else if($align=="BL"){
$x = $offsetX;
$y = ($bh-$h-$offsetY);
} else if($align=="TL"){
$x = $offsetX;
$y = $offsetY;
} else if($align=="TR"){
$x = ($bw-$w-$offsetX);
$y = $offsetY;
} else{
$x = ($bw-$w-$offsetX)/2;
$y = ($bh-$h-$offsetY)/2;
}
}
/**
* 当前素材宽度
* @return number
*/
public function width()
{
return imagesx($this->res);
}
/**
* 当前素材高度
* @return number
*/
public function height()
{
return imagesy($this->res);
}
/**
* 当前素材resource
* @return resource
*/
public function res(){
return $this->res;
}
/**
* 保存到文件
* @param string $file
* @param string $type
* @return Img
*/
public function save($file="",$type=null){
if($type==null){
$type = $this->type;
if($this->alphaed){
$type = "png";
}
}
self::saveTo($this->res, $file, $type);
return $this;
}
/**
* 销毁当前图
*/
public function destory(){
if($this->res){
@imagedestroy($this->res);
$this->res = false;
}
}
/**
* 保存ImageResource到文件
* @param resource $image
* @param string $file
* @param string $type
*/
private static function saveTo($image,$file,$type="jpg"){
if(!$file || empty($file)){
$file = null;
header("content-type: image/".$type);
}
if($type=="png"){
imagepng($image, $file);
}else if($type=="gif"){
$transColor = imagecolorallocatealpha($image, 255, 255, 255, 127);
imagecolortransparent($image, $transColor);
imagegif($image, $file);
}else{
imagejpeg($image, $file, 100);
}
}
/**
* @param string $src 图片文件文件
* @param int $width 目标尺寸
* @param int $height 目标尺寸
* @param string $toFile 缩放后存储文件,如果不设置则会覆盖源图路径
* @param boolean $ratio 保持比例
* @param boolean $thumbnail 如果为false支持等比放大 true则只支持等比从大到小
*/
private static function resizeImp($res, $width, $height, $ratio=TRUE, $thumbnail=FALSE){
if($height===false){
$height = $width;
}
$oldW = imagesx($res);
$oldH = imagesy($res);
self::scale($width, $height, $oldW, $oldH, $ratio, $thumbnail);
$img = imagecreatetruecolor($width, $height);
$alpha = imagecolorallocatealpha($img, 255, 255, 255, 127);
imagefill($img, 0, 0, $alpha);
imagecopyresampled($img, $res, 0, 0, 0, 0, $width, $height, $oldW, $oldH);
imagesavealpha($img, true);
return $img;
}
/**
* 根据是否保持比例是否缩略图,计算缩放后的真实尺寸
* @param int $toWidth toWidth
* @param int $toHeight toHeight
* @param int $srcWidth srcWidth
* @param int $srcHeight srcHeight
* @param boolean $ratio 保持比例
* @param boolean $thumbnail 如果为false支持等比放大 true则只支持等比从大到小
*/
private static function scale(&$toWidth,&$toHeight,$srcWidth,$srcHeight, $ratio=TRUE, $thumbnail=FALSE){
if($ratio || $thumbnail){
if($thumbnail && ($srcWidth<$toWidth && $srcHeight<$toHeight)){
$toWidth = $srcWidth;
$toHeight = $srcHeight;
}else{
if (($toWidth/$toHeight) <= ($srcWidth/$srcHeight)){
$toHeight = intval($toWidth * ($srcHeight / $srcWidth));
}else{
$toWidth = intval($toHeight * ($srcWidth / $srcHeight));
}
}
}
}
private static function makeColor($img, $rgba){
$b = $rgba&0xff;
$rgba >>= 8;
$g = ($rgba)&0xff;
$rgba >>= 8;
$r = ($rgba)&0xff;
$rgba >>= 8;
$a = ($rgba)&0xff;
$c = imagecolorallocatealpha($img, $r, $g, $b, $a);
if($rgba==0x7fffffff){
imagecolortransparent($img, $c);
}
return $c;
}
private static function typeStr($type){
if($type == IMAGETYPE_PNG){
return "png";
}else if($type == IMAGETYPE_GIF){
return "gif";
}else if($type == IMAGETYPE_BMP){
return "bmp";
}
return "jpg";
}
}
?>