Skip to content

Instantly share code, notes, and snippets.

@yuka2py
Created February 27, 2014 12:16
Show Gist options
  • Save yuka2py/9248997 to your computer and use it in GitHub Desktop.
Save yuka2py/9248997 to your computer and use it in GitHub Desktop.
出来は悪いのですが、よく使うしよく修正するので、とりあえずここに置いておきます。
<?php
class ImageLoadingFailedException extends ErrorException {}
class UnSupportedImageException extends ErrorException {}
/**
* Simply image processing descriptor.
* @see http://jp.php.net/manual/ja/ref.image.php
* @author yuka2py
*/
class Image
{
const RESIZE_POLICY_IN_BOUND = 'InBound';
const RESIZE_POLICY_OUT_BOUND = 'OutBound';
const RESIZE_POLICY_FIT = 'Fit';
static private $_suppoted_type_and_extensions = array(
IMAGETYPE_PNG => 'png',
IMAGETYPE_JPEG => 'jpeg',
IMAGETYPE_GIF => 'gif',
);
/**
* リサイズ後のサイズを計算して返す
* @return array array(width, height)
* @param integer $width 目標サイズ
* @param integer $height 目標サイズ
* @param integer $src_width ソースサイズ
* @param integer $src_height ソースサイズ
* @param string $resize_policy リサイズの方針
* @param boolean $expand 目標サイズよりソースサイズが小さい時、拡大するか否か
*/
static private function _calc_resize(
$width, $height,
$src_width, $src_height,
$resize_policy,
$expand) {
$sx = $width / $src_width;
$sy = $height / $src_height;
switch ($resize_policy) {
case Image::RESIZE_POLICY_FIT:
$sx = $width / $src_width;
$sy = $height / $src_height;
break;
case Image::RESIZE_POLICY_IN_BOUND:
$sx = $width / $src_width;
$sy = $height / $src_height;
$sx = $sy = min($sx, $sy);
break;
case Image::RESIZE_POLICY_OUT_BOUND:
$sx = $width / $src_width;
$sy = $height / $src_height;
$sx = $sy = max($sx, $sy);
break;
default:
throw ErrorException(
'Unexpected resize policy: ' . $resize_policy);
}
$w = $src_width * $sx;
$h = $src_height * $sy;
if ( ! $expand) {
switch ($resize_policy) {
case Image::RESIZE_POLICY_FIT:
$w = min($w, $src_width);
$h = min($h, $src_height);
break;
case Image::RESIZE_POLICY_IN_BOUND:
case Image::RESIZE_POLICY_OUT_BOUND:
if ($src_width < $w or $src_height < $h) {
$w = $src_width;
$h = $src_height;
}
break;
}
}
$w = round($w);
$h = round($h);
return array($w, $h);
}
/**
* Create image instance.
* @return Image
* @param mixed $src file path or url path or resource.
*/
static public function create($src, $type=null) {
return new Image($src, $type);
}
/**
* Load image, return resource
* @return array array($resource, $type);
* @param string $src file path or url.
*/
static public function load_resource($src) {
list(,, $type) = getimagesize($src);
switch ($type) {
case IMAGETYPE_PNG:
$resource = imagecreatefrompng($src);
break;
case IMAGETYPE_GIF:
$resource = imagecreatefromgif($src);
break;
case IMAGETYPE_JPEG:
$resource = imagecreatefromjpeg($src);
break;
default:
throw new UnSupportedImageException(var_export($type, 1)." at $src");
}
return array($resource, $type);
}
/**
* Save resource to file.
* @param resource $resource
* @param string $type
* @param string $path sava file path. if specify null then flush to stream.
* * @param integer $quality
*/
static public function flush_resource($resource, $type, $path=null, $quality=90) {
switch ($type) {
case IMAGETYPE_PNG:
imagepng($resource, $path);
break;
case IMAGETYPE_GIF:
imagegif($resource, $path);
break;
case IMAGETYPE_JPEG:
imagejpeg($resource, $path, $quality);
break;
default:
throw new UnSupportedImageException("$type @ $path");
}
}
/**
* Resizing image file.
* @return void
* @param string $source Image file path.
* @param integer $w Destination width
* @param integer $h Destination height.
* @param string $resize_policy[default=self::RESIZE_POLICY_IN_BOUND] Risizing policy
* @param boolean $expand[default=false] The original image is smaller than specified, whether or not to expand. Default is false means no expand.
* @param mixed $dst_image_type[default=false is same origin] Destination file type. Default is same original file type.
* @param mixed $destination[default=false is same origin] Destination file path. Default is same original file path. If original from url then flush to stream.
*/
public static function resize_image_file($source,
$w, $h,
$resize_policy=Image::RESIZE_POLICY_IN_BOUND,
$expand=false,
$dst_image_type=false,
$destination=false) {
list ($src_image, $src_image_type) = Image::load_resource($source);
$sw = imagesx($src_image);
$sh = imagesy($src_image);
if (empty($dst_image_type)) {
$dst_image_type = $src_image_type;
}
if ($destination===false) {
$destination = file_exists($source) ? $source : null;
}
list ($w, $h) = Image::_calc_resize(
$w, $h, $sw, $sh,
$resize_policy, $expand);
// if ($sw !== $w or $sh === $h) {
$dst_image = imageCreateTrueColor($w, $h);
imageCopyResampled($dst_image, $src_image,0,0,0,0, $w, $h, $sw, $sh);
Image::flush_resource($dst_image, $dst_image_type, $destination);
// }
// else if ($src_file_path !== $dst_file_path) {
// copy($src_file_path, $dst_file_path);
// }
}
/**
* 画像拡張子をサポートしているか?
* @return boolean
* @param string $ext
*/
static public function is_supported_image_extension($ext) {
return in_array(strtolower($ext), self::supported_image_extensions());
}
/**
* 画像タイプをサポートしているか?
* @return boolean
* @param string $ext
*/
static public function is_supported_image_type($type) {
return in_array($type, self::supported_image_types());
}
/**
* サポートする画像拡張子の配列で返す。
* @return array
*/
static public function supported_image_extensions() {
return array_values(self::$_suppoted_type_and_extensions);
}
/**
* サポートする画像タイプを配列で返す。
* @return array
*/
static public function supported_image_types() {
return array_keys(self::$_suppoted_type_and_extensions);
}
protected $_resource;
protected $_type; //画像の想定タイプ
protected $_filepath; //現在のファイルパス
protected function __construct($resource, $type=null) {
if (is_string($resource)) {
$this->_filepath = $resource;
list ($resource, $type) = Image::load_resource($resource);
}
$this->_resource = $resource;
$this->_type = $type;
}
/**
* 画像の幅を返す。
*/
public function width() {
return imagesx($this->_resource);
}
/**
* 画像の高さを返す。
*/
public function height() {
return imagesy($this->_resource);
}
/**
* 画像の形式を返す。
*/
public function type($type=null) {
if (func_num_args() > 0) {
$this->_type = $type;
}
if (empty($this->_type)) {
throw ErrorException('Image type not set yet.');
}
return $this->_type;
}
/**
* 画像のファイルパスを帰す。
*/
public function filepath($filepath=null) {
if (func_num_args() > 0) {
$this->_filepath = $filepath;
}
if (empty($this->_filepath)) {
throw new ErrorException('File path not set yet.');
}
return $this->_filepath;
}
/**
* 画像タイプに該当する拡張子を返す。
* @return string
*/
public function extension() {
return self::$_suppoted_type_and_extensions[$this->type()];
}
/**
* Resizing image.
* @return Image return myself.
* @param integer $w Destination width
* @param integer $h Destination height.
* @param string $resize_policy[optional=true] Risizing policy
* @param boolean $expand[optional=false] The original image is smaller than specified, whether or not to expand. Default is false means no expand.
*/
public function resize(
$w, $h,
$resize_policy=self::RESIZE_POLICY_IN_BOUND,
$expand=false) {
$sw = $this->width();
$sh = $this->height();
list ($w, $h) = Image::_calc_resize($w, $h, $sw, $sh, $resize_policy, $expand);
if ($sw != $w or $sh != $h) {
$new = imageCreateTrueColor($w, $h);
imageCopyResampled($new, $this->_resource, 0, 0, 0, 0, $w, $h, $sw, $sh);
$this->_resource = $new;
}
return $this;
}
/**
* Save to file.
* @param integer $type Image type
* @param string $path File path location
* @param integer $quality Quality value for JPEG. Range of 0 to 100. Default is 90.
*/
public function flush($type, $path=null, $quality=90) {
$path or $path = $this->filepath();
$type or $type = $this->type();
Image::flush_resource($this->_resource, $path, $type, $quality);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment