Initial commit
This commit is contained in:
260
pluf/src/Pluf/Image/Thumbnail.php
Normal file
260
pluf/src/Pluf/Image/Thumbnail.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# This file is part of Plume Framework, a simple PHP Application Framework.
|
||||
# Copyright (C) 2001-2007 Loic d'Anterroches and contributors.
|
||||
#
|
||||
# Plume Framework is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Plume Framework is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Generate the thumbnail of an image.
|
||||
*
|
||||
* Sample usage.
|
||||
*
|
||||
* $thumbnail = new Pluf_Image_Thumbnail($thumbnail_folder, $source_image);
|
||||
* if (!$thumbnail->exists()) {
|
||||
* $thumbnail_filename = $thumbnail->generate();
|
||||
* }
|
||||
*
|
||||
*/
|
||||
class Pluf_Image_Thumbnail
|
||||
{
|
||||
protected $dir = ''; /**< Path to the thumbnail folder. */
|
||||
protected $filename = ''; /**< Filename of the last created thumbnail. */
|
||||
public $source = ''; /**< Full path to the source file. */
|
||||
public $size = array(120, 120); /** Max width and heigth of the thumb. */
|
||||
|
||||
/**
|
||||
* Init the thumbnail class.
|
||||
*/
|
||||
public function __construct($dir, $source='')
|
||||
{
|
||||
$this->dir = $dir;
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of a thumbnail from the image name, the image
|
||||
* name can include a path this is just a md5() operation.
|
||||
* If the height and the width are given, the info is used to
|
||||
* generate the name, else not.
|
||||
*
|
||||
* @param array Optional size.
|
||||
* @return string Filename of the thumbnail.
|
||||
*/
|
||||
public function getName($size=null)
|
||||
{
|
||||
$name = md5($this->source);
|
||||
if ($size === null) {
|
||||
$size = $this->size;
|
||||
}
|
||||
return $name.'-'.$size[0].'-'.$size[1].'.png';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full path to the thumbnail.
|
||||
*/
|
||||
function getPath()
|
||||
{
|
||||
return $this->dir.'/'.$this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the thumbnail exists.
|
||||
*/
|
||||
function exists()
|
||||
{
|
||||
return file_exists($this->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the last created thumbnail
|
||||
* return the same results as the builtin getimagesize PHP function.
|
||||
*/
|
||||
function getSize()
|
||||
{
|
||||
if (file_exists($this->getPath())) {
|
||||
return getimagesize($this->getPath());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create thumbnail of an image, proportions are kept.
|
||||
*
|
||||
* @return mixed Filename or false.
|
||||
*/
|
||||
function generate()
|
||||
{
|
||||
if (!file_exists($this->source)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (($size = @getimagesize($this->source)) === false) {
|
||||
return false;
|
||||
}
|
||||
list($w, $h) = $this->size;
|
||||
$type = $size[2];
|
||||
$H = $size[1];
|
||||
$W = $size[0];
|
||||
|
||||
if ($type == '1') {
|
||||
$function = 'imagecreatefromgif';
|
||||
} elseif ($type == '2') {
|
||||
$function = 'imagecreatefromjpeg';
|
||||
} elseif ($type == '3') {
|
||||
$function = 'imagecreatefrompng';
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (!function_exists($function)) {
|
||||
return false;
|
||||
}
|
||||
if (($img = @$function($this->source)) == false) {
|
||||
return false;
|
||||
}
|
||||
// get the zoom factors and the thumbnail height and width
|
||||
$rB = $H/$W;
|
||||
$rS = $h/$w;
|
||||
if (($H > $h) && ($W > $w)) {
|
||||
if ($rB > $rS) {
|
||||
$height = $h;
|
||||
$width = $height/$rB;
|
||||
} else {
|
||||
$width = $w;
|
||||
$height = $width*$rB;
|
||||
}
|
||||
} elseif ($H > $h) {
|
||||
$height = $h;
|
||||
$width = $height/$rB;
|
||||
} elseif ($W > $w) {
|
||||
$width = $w;
|
||||
$height = $width*$rB;
|
||||
} else {
|
||||
$height = $H;
|
||||
$width = $W;
|
||||
}
|
||||
$zx = $W/$width;
|
||||
$zy = $H/$height;
|
||||
|
||||
if (Pluf_Image_Thumbnail::gd_version() >= 2) {
|
||||
if (($img2=imagecreatetruecolor(round($width),round($height)))===false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (($img2=ImageCreate(round($width),round($height)))===false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$this->resampleBicubic($img2,$img,0,0,0,0,$width,$height,$zx,$zy);
|
||||
if (@imagepng($img2,$this->getPath(),9) === false) {
|
||||
return false;
|
||||
}
|
||||
imagedestroy($img2);
|
||||
if (@file_exists($this->getPath())) {
|
||||
return $this->getPath();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current GD version. Need the output buffering functions.
|
||||
*/
|
||||
public static function gd_version()
|
||||
{
|
||||
static $gd_version_number = null;
|
||||
if ($gd_version_number === null) {
|
||||
// Use output buffering to get results from phpinfo()
|
||||
// without disturbing the page we're in. Output
|
||||
// buffering is "stackable" so we don't even have to
|
||||
// worry about previous or encompassing buffering.
|
||||
ob_start();
|
||||
phpinfo(8);
|
||||
$module_info = ob_get_contents();
|
||||
ob_end_clean();
|
||||
if (preg_match("/\bgd\s+version\b[^\d\n\r]+?([\d\.]+)/i",
|
||||
$module_info,$matches)) {
|
||||
$gd_version_number = $matches[1];
|
||||
} else {
|
||||
$gd_version_number = '0';
|
||||
}
|
||||
}
|
||||
return $gd_version_number;
|
||||
|
||||
}
|
||||
|
||||
/* ========================================================================
|
||||
* Private functions, should not be called from outside of the class.
|
||||
* ========================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resample the image
|
||||
* http://www.php.net/manual/en/function.imagecopyresized.php
|
||||
*/
|
||||
protected function resampleBicubic(&$dst, &$src, $dstx, $dsty, $srcx,
|
||||
$srcy, $w, $h, $zoomX, $zoomY='')
|
||||
{
|
||||
if (!$zoomY) {
|
||||
$zoomY = $zoomX;
|
||||
}
|
||||
$palsize = ImageColorsTotal($src);
|
||||
for ($i = 0; $i<$palsize; $i++) {
|
||||
$colors = ImageColorsForIndex($src, $i);
|
||||
ImageColorAllocate($dst, $colors['red'], $colors['green'],
|
||||
$colors['blue']);
|
||||
}
|
||||
$zoomX2 = (int)($zoomX/2);
|
||||
$zoomY2 = (int)($zoomY/2);
|
||||
$dstX = imagesx($dst);
|
||||
$dstY = imagesy($dst);
|
||||
$srcX = imagesx($src);
|
||||
$srcY = imagesy($src);
|
||||
|
||||
for ($j=0; $j<($h-$dsty); $j++) {
|
||||
$sY = (int)($j*$zoomY) + $srcy;
|
||||
$y13 = $sY+$zoomY2;
|
||||
$dY = $j+$dsty;
|
||||
|
||||
if (($sY >= $srcY) or ($dY >= $dstY) or ($y13 >= $srcY)) {
|
||||
break 1;
|
||||
}
|
||||
for ($i=0; $i<($w-$dstx); $i++) {
|
||||
$sX = (int)($i*$zoomX)+$srcx;
|
||||
$x34 = $sX+$zoomX2;
|
||||
$dX = $i+$dstx;
|
||||
if (($sX >= $srcX) or ($dX >= $dstX) or ($x34 >= $srcX)) {
|
||||
break 1;
|
||||
}
|
||||
$c1 = ImageColorsForIndex($src, ImageColorAt($src, $sX, $y13));
|
||||
$c2 = ImageColorsForIndex($src, ImageColorAt($src, $sX, $sY));
|
||||
$c3 = ImageColorsForIndex($src, ImageColorAt($src, $x34, $y13));
|
||||
$c4 = ImageColorsForIndex($src, ImageColorAt($src, $x34, $sY));
|
||||
|
||||
$r = ($c1['red']+$c2['red']+$c3['red']+$c4['red'])/4;
|
||||
$g = ($c1['green']+$c2['green']+$c3['green']+$c4['green'])/4;
|
||||
$b = ($c1['blue']+$c2['blue']+$c3['blue']+$c4['blue'])/4;
|
||||
|
||||
ImageSetPixel($dst, $dX, $dY, ImageColorClosest($dst, $r,
|
||||
$g, $b));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user