Created
March 15, 2012 18:43
-
-
Save jonathonbyrdziak/2045951 to your computer and use it in GitHub Desktop.
A Wordpress class that allows you to place watermarks on your images.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* The constants defined here are used as a fallback to whatever options you | |
* end up specifying specifically. | |
* | |
* @var constant string | |
*/ | |
define('WATERMARK_SOURCE', ABSPATH.'/wp-content/themes/mytheme/images/fb_thumb_watermark.png'); | |
define('WATERMARK_ORIENTATION', 'bottom right'); | |
define('WATERMARK_PADDING', 5); | |
define('WATERMARK_OPACITY', 90); | |
define('WATERMARK_BACKUP', true); | |
/** | |
* Preparing your theme to save watermarks on every image is simple. First | |
* do so by activating support for watermarks. The default setting will take a backup | |
* of your original upload and then apply a watermark to the primary image. This | |
* causes every image size crunched by wordpress to display the watermark as well. | |
* | |
* `add_theme_support('watermarks');` | |
* | |
* Additionally, you may specify individual sizes that you would like watermarks applied to. | |
* By stating 'all' as a parameter, bo backup will be taken, however the primary image | |
* will also not be watermarked. Every crunched image size of the original will receive | |
* a watermark. This process is slower then the default, but more accurate. | |
* | |
* `add_watermark_on_size('all');` | |
* | |
*/ | |
add_theme_support('watermarks'); | |
add_watermark_on_size('original', array( | |
'watermark' => ABSPATH.'/wp-content/themes/mytheme/images/master_watermark.png', | |
'orientation' => 'bottom center', | |
'opacity' => 90, | |
'extendcanvas' => true, | |
'horizontalline'=> true, | |
'backup' => true, | |
)); | |
add_watermark_on_size('all', array( | |
'watermark' => ABSPATH.'/wp-content/themes/mytheme/images/master_watermark.png', | |
'opacity' => 90, | |
)); | |
add_watermark_on_size(150, array( | |
'watermark' => ABSPATH.'/wp-content/themes/mytheme/images/fb_thumb_watermark_80.png', | |
'orientation' => 'center center', | |
'padding' => 5, | |
)); | |
/** | |
* Method is designed to add a string to the image, this is not part of the class | |
* just something that i needed on my last project | |
* | |
* @param array $args | |
* @param object $instance | |
*/ | |
add_filter('redrokk_watermark_args', 'redrokk_imageline', 20, 2); | |
function redrokk_imageline( $args, $instance ) | |
{ | |
if ($instance->_pData['x'] != 150) { | |
// creating the image line | |
$line = imagecolorallocate( | |
$line, | |
imagecreate($instance->_pData['x'], $instance->_pData['y']), | |
0, 0, 0); | |
// merging the line with the primary image | |
$y = ceil($instance->getDestinationY() + ($instance->_wData['y'] /2)); | |
imagelinethick( | |
$args['primary'], | |
0, //x1 | |
$y, //y1 | |
$instance->_pData['x'], //x2 | |
$y, //y2 | |
$line, | |
$instance->_wData['y'] + $instance->padding | |
); | |
} | |
return $args; | |
} | |
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1) | |
{ | |
/* this way it works well only for orthogonal lines | |
imagesetthickness($image, $thick); | |
return imageline($image, $x1, $y1, $x2, $y2, $color); | |
*/ | |
if ($thick == 1) { | |
return imageline($image, $x1, $y1, $x2, $y2, $color); | |
} | |
$t = $thick / 2 - 0.5; | |
if ($x1 == $x2 || $y1 == $y2) { | |
return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color); | |
} | |
$k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q | |
$a = $t / sqrt(1 + pow($k, 2)); | |
$points = array( | |
round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a), | |
round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a), | |
round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a), | |
round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a), | |
); | |
imagefilledpolygon($image, $points, 4, $color); | |
return imagepolygon($image, $points, 4, $color); | |
} | |
// using api | |
$filepath = watermark_image( $image, $watermark = NULL, $orientation = 'bottom right', $padding = 5, $opacity = 90 ); | |
// using api as OOP | |
// specifically watermarking a single image | |
$water = redrokk_watermark_class::getInstance(); | |
$water->set('primary', site_url('wp-content/uploads/2012/02/anuploadedimage.jpg')); | |
$water->set('watermark', site_url('wp-content/themes/mytheme/images/logo.png')); | |
$water->set('orientation', 'bottom left'); // or any combination thereof | |
//save the primary file over the top of itself | |
$path = $water->save(); | |
//save the primary file with a new filename | |
$path = $water->save( 'newFileName' ); | |
//show me the results | |
header('content-type: image/jpeg'); | |
echo $water->getCompleted(); // outputs the image without saving it | |
die(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @Author Anonymous | |
* @link http://www.redrokk.com | |
* @Package Wordpress | |
* @SubPackage RedRokk Library | |
* @copyright Copyright (C) 2011+ Redrokk Interactive Media | |
* | |
* @version 0.1 | |
*/ | |
defined('ABSPATH') or die('cannot load directly'); | |
/** | |
* Function prepares the current theme for watermarking | |
* | |
* @return string | |
*/ | |
add_action('init', 'theme_supports_watermarks', 100); | |
function theme_supports_watermarks() | |
{ | |
if (!current_theme_supports('watermarks')) return false; | |
add_filter('update_attached_file', 'watermark_image', 1, 1); | |
add_filter('image_make_intermediate_size', 'redrokk_watermarked_thumbs', 1, 1); | |
add_filter('wp_generate_attachment_metadata', 'redrokk_watermarked_original', 20, 2); | |
} | |
/** | |
* | |
* | |
* @param integer $size | |
*/ | |
function add_watermark_on_size( $size, $args = array() ) | |
{ | |
global $watermark; | |
if ($watermark === null) { | |
$watermark = array(); | |
} | |
if (!isset($watermark[$size])) { | |
$watermark[$size] = array(); | |
} | |
$watermark[$size][] = $args; | |
return; | |
} | |
/** | |
* Function will overlay the watermark onto the original image | |
* | |
* @param int $attachment_id Attachment Id to process. | |
* @param string $file Filepath of the Attached image. | |
* @return mixed Metadata for attachment. | |
*/ | |
function redrokk_watermarked_original( $metadata, $attachment_id ) | |
{ | |
global $watermark; | |
if (isset($watermark['original'])) | |
{ | |
foreach ((array)$watermark['original'] as $args) | |
{ | |
$water = redrokk_watermark_class::getInstance( | |
ABSPATH.'wp-content'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.$metadata['file'], | |
$args | |
); | |
$paths = $water->save(); | |
} | |
} | |
return $metadata; | |
} | |
/** | |
* Function will overlay the watermark onto the specific image size | |
* | |
* @param $resized_file | |
*/ | |
function redrokk_watermarked_thumbs( $resized_file ) | |
{ | |
global $watermark; | |
if ($watermark !== null) | |
{ | |
list($width, $height, $type, $attr) = getimagesize($resized_file); | |
// if the size matches then watermark this image | |
$w = in_array($width, array_keys($watermark)); | |
if ($w || in_array('all', array_keys($watermark))) | |
{ | |
foreach ((array)$watermark[ $w ?$width :'all'] as $args) | |
{ | |
$water = redrokk_watermark_class::getInstance($resized_file, $args); | |
$paths = $water->save(); | |
} | |
} | |
} | |
return $resized_file; | |
} | |
/** | |
* Function will overlay the given watermark on the image and | |
* then save the new file, overwriting the given image | |
* | |
* @param string $image | |
* @param string $watermark | |
* @param string $orientation | |
* @param int $padding | |
* @param int $opacity | |
*/ | |
function watermark_image( $image, $watermark = NULL, $orientation = NULL, $padding = NULL, $opacity = NULL ) | |
{ | |
global $watermark; | |
// close if theres a specific size | |
if ($watermark !== null) return $image; | |
//get the real path | |
$image = str_replace(site_url(), ABSPATH, $image); | |
$path = pathinfo( $image ); | |
$backup = $path['dirname'].DIRECTORY_SEPARATOR | |
. $path['filename'] | |
. '-original' . '.' . $path['extension']; | |
// making sure that we don't mess up any important images | |
if (!file_exists( $backup )) | |
{ | |
if (!copy( $image, $backup )) | |
{ | |
// define('WATERMARK_BACKUP', false); | |
if (!defined('WATERMARK_BACKUP')) | |
{ | |
trigger_error(__FUNCTION__.': Could not create a backup of the original,' | |
. " to override define('WATERMARK_BACKUP', false);"); | |
return $image; | |
} | |
elseif (WATERMARK_BACKUP) | |
{ | |
trigger_error(__FUNCTION__.': Could not create a backup of the original.'); | |
return $image; | |
} | |
} | |
} // just making sure that we dont add the watermark more then once | |
else | |
{ | |
@copy( $backup, $image ); | |
} | |
// setting the stage | |
$args = array(); | |
if ($watermark !== NULL) { | |
$args['watermark'] = $watermark; | |
} | |
if ($orientation !== NULL) { | |
$args['orientation'] = $orientation; | |
} | |
if ($padding !== NULL) { | |
$args['padding'] = $padding; | |
} | |
if ($opacity !== NULL) { | |
$args['opacity'] = $opacity; | |
} | |
$water = redrokk_watermark_class::getInstance($image, $args); | |
$path = $water->save(); | |
return $path['file']; | |
} | |
/** | |
* @author Anonymous | |
* @tutorial https://gist.github.com/2045951 | |
* | |
*/ | |
class redrokk_watermark_class | |
{ | |
/** | |
* Contains the original watermark image | |
* | |
* The file should be a PNG-8 format file, not PNG-24. | |
* There’s a bug in the current version of GD, which doesn’t support | |
* PNG-24 correctly. | |
* | |
* @var string | |
*/ | |
var $watermark; | |
/** | |
* Contains a block of information about the image | |
* | |
* @var string | |
*/ | |
var $_wData = array(); | |
/** | |
* Contains the original image to watermark | |
* | |
* @var string | |
*/ | |
var $primary; | |
/** | |
* Contains a block of information about the image | |
* | |
* @var string | |
*/ | |
var $_pData = array(); | |
/** | |
* Contains the orientation for the watermark. System defaults to the bottom | |
* right. | |
* | |
* @example | |
* bottom | |
* top | |
* left | |
* right | |
* | |
* @var string | |
*/ | |
var $orientation = 'bottom right'; | |
/** | |
* How much padding between the watermark and the edges | |
* | |
* @var string|array | |
*/ | |
var $padding = 5; | |
/** | |
* The opacity strength to apply when merging. 0 is hidden and 100 is full opacity. | |
* | |
* @var int | |
*/ | |
var $opacity = 90; | |
/** | |
* We only need to run the merge once. | |
* | |
* @var boolean | |
*/ | |
var $_merged = false; | |
/** | |
* The relation from the top | |
* | |
* @var string | |
*/ | |
var $top = 'bottom'; | |
/** | |
* The relation from the left | |
* | |
* @var string | |
*/ | |
var $left = 'right'; | |
/** | |
* Parameters determines whether or not the system will use smart scaling | |
* and adjust the size of the watermark, according to the image size. | |
* | |
* @var boolean | |
*/ | |
var $scale = true; | |
/** | |
* Extends the canvas beyond the image for the watermark | |
* | |
* @var boolean | |
*/ | |
var $extendcanvas = false; | |
/** | |
* Adds a background line behind the watermark | |
* | |
* @var boolean | |
*/ | |
var $horizontalline = false; | |
/** | |
* Shall we save an original? | |
* | |
* @var boolean | |
*/ | |
var $backup = false; | |
/** | |
* Constructor. | |
* | |
*/ | |
function __construct( $options = array() ) | |
{ | |
// define('WATERMARK_SOURCE', '/path/to/file.png'); | |
if (defined('WATERMARK_SOURCE')) { | |
$this->set('watermark', WATERMARK_SOURCE); | |
} | |
//define('WATERMARK_ORIENTATION', 'bottom right'); | |
if (defined('WATERMARK_ORIENTATION')) { | |
$this->set('orientation', WATERMARK_ORIENTATION); | |
} | |
//define('WATERMARK_PADDING', 5); | |
if (defined('WATERMARK_PADDING')) { | |
$this->set('padding', WATERMARK_PADDING); | |
} | |
//define('WATERMARK_OPACITY', 90); | |
if (defined('WATERMARK_OPACITY')) { | |
$this->set('opacity', WATERMARK_OPACITY); | |
} | |
// initializing | |
$this->setProperties($options); | |
} | |
/** | |
* Function saves the newly created image into the uploads folder and returns | |
* an array which includes the file path. | |
* | |
* @see wp_upload_bits(); http://codex.wordpress.org/Function_Reference/wp_upload_bits | |
* | |
* @param string $path | |
* | |
* @return array | |
*/ | |
function save( $path = NULL ) | |
{ | |
do_action(get_class().'::save', $this); | |
//merging if we have not yet merged | |
$bits = $this->getWatermarkedImageResource(); | |
if ($path === NULL) { | |
$path = $this->primary; | |
} | |
if ($this->backup) | |
{ | |
rename( $path, | |
$this->_pData['path'].'/'.$this->_pData['name'].".original.".$this->_pData['ext'] ); | |
} | |
$parts = pathinfo( $path ); | |
$name = $this->_pData['name'].'.'.$parts['extension']; | |
$wp_filetype = wp_check_filetype( $name ); | |
if (!$wp_filetype['ext']) { | |
return array( 'error' => __( 'Invalid file type' ) ); | |
} | |
if (!wp_mkdir_p( dirname( $path ) )) { | |
$message = sprintf( __( 'Unable to create directory %s. Is its parent directory writable by the server?' ), dirname( $new_file ) ); | |
return array( 'error' => $message ); | |
} | |
$ifp = @ fopen( $path, 'wb' ); | |
if (!$ifp) { | |
return array( 'error' => sprintf( __( 'Could not write file %s' ), $path ) ); | |
} | |
@fwrite( $ifp, $bits ); | |
fclose( $ifp ); | |
clearstatcache(); | |
// Set correct file permissions | |
$stat = @ stat( dirname( $path ) ); | |
$perms = $stat['mode'] & 0007777; | |
$perms = $perms & 0000666; | |
@ chmod( $path, $perms ); | |
clearstatcache(); | |
// Compute the URL | |
$url = str_replace(ABSPATH, site_url().'/', $path); | |
$options = array( 'file' => $path, 'url' => $url, 'error' => false ); | |
if (0) { | |
echo '<pre> $options : '; | |
var_export($options); | |
echo "\r".'$this : '; | |
print_r(get_object_vars($this)); | |
echo '</pre>'; | |
die(); | |
} | |
return $options; | |
} | |
/** | |
* Method merges the watermark image with the primary image to be watermarked, | |
* saves the final image and returns the path | |
* | |
* @notice use of the PNG format; GD 2.0+ has removed compatibility with GIF images | |
* | |
* @see imagecopymerge | |
* int imagecopymerge ( | |
* resource dst_im, | |
* resource src_im, | |
* int dst_x, | |
* int dst_y, | |
* int src_x, | |
* int src_y, | |
* int src_w, | |
* int src_h, | |
* int pct ) | |
* | |
* @tutorial | |
* Copy a part of src_im onto dst_im starting at the x,y coordinates src_x, | |
* src_y with a width of src_w and a height of src_h. The portion defined will | |
* be copied onto the x,y coordinates, dst_x and dst_y. The two images will be | |
* merged according to pct which can range from 0 to 100. | |
* | |
*/ | |
function merge() | |
{ | |
// merge the image if it has not yet been merged | |
if (!$this->_merged) | |
{ | |
// additional adjustments | |
$this->canvassize(); | |
$this->imageline(); | |
// offering others an opportunity | |
$args = apply_filters('redrokk_watermark_args', array( | |
'primary' => $this->_pData['img'], | |
'watermark' => $this->_wData['img'], | |
'dst_x' => $this->getDestinationX(), | |
'dst_y' => $this->getDestinationY(), | |
'src_x' => 0, | |
'src_y' => 0, | |
'src_w' => $this->_wData['x'], | |
'src_h' => $this->_wData['y'], | |
'opacity' => $this->opacity | |
), $this); | |
$this->_merged = call_user_func_array('imagecopymerge', $args); | |
} | |
return $this->_merged; | |
} | |
/** | |
* Returns the image as a string | |
* | |
*/ | |
function getWatermarkedImageResource() | |
{ | |
$this->merge(); | |
ob_start(); | |
imagejpeg( $this->_pData['img'] ); | |
return ob_get_clean(); | |
} | |
/** | |
* Creates an image from a given file | |
* | |
* @param string $file | |
* @param string $type | |
*/ | |
function getImageResource( $file, $type = 3 ) | |
{ | |
//initializing | |
$img = false; | |
if ($type === NULL) { | |
$size = getimagesize( $file ); | |
$type = $size['mime']; | |
} | |
switch ($type) { | |
default: | |
case 3: | |
case '3': | |
case 'image/png': | |
$img = imagecreatefrompng($file); | |
break; | |
case 2: | |
case '2': | |
case 'image/jpeg': | |
$img = imagecreatefromjpeg($file); | |
break; | |
case 'image/gif': | |
$img = imagecreatefromgif($file); | |
break; | |
} | |
return $img; | |
} | |
/** | |
* Determines information about the given image and returns it as an array | |
* | |
* @param $file | |
*/ | |
function getImageData( $file ) | |
{ | |
//initializing | |
if (!$size = getimagesize( $file )) return false; | |
$data = array(); | |
list($width, $height, $type, $attr) = $size; | |
$data['x'] = $width; | |
$data['y'] = $height; | |
$data['mime'] = $type; | |
$path_parts = pathinfo( $file ); | |
$data['path'] = $path_parts['dirname']; | |
$data['name'] = $path_parts['filename']; | |
$data['ext'] = $path_parts['extension']; | |
$data['img'] = $this->getImageResource( $file, $type ); | |
return $data; | |
} | |
/** | |
* Returns the proper y value for the given orientation | |
* | |
*/ | |
function getDestinationY() | |
{ | |
// if top | |
if ($this->isTop()) | |
{ | |
return $this->getPaddingY(); | |
} | |
// if center | |
elseif ($this->isYCenter()) | |
{ | |
return @ceil( ($this->_pData['y'] - $this->_wData['y']) / 2 ); | |
} | |
// bottom is default | |
return $this->_pData['y'] - $this->_wData['y'] - $this->getPaddingY(); | |
} | |
/** | |
* Returns the proper x value for the given orientation | |
* | |
*/ | |
function getDestinationX() | |
{ | |
// if left | |
if ($this->isLeft()) | |
{ | |
return $this->getPaddingX(); | |
} | |
// if center | |
elseif ($this->isXCenter()) | |
{ | |
return @ceil( ($this->_pData['x'] - $this->_wData['x']) / 2 ); | |
} | |
// right is default | |
return $this->_pData['x'] - $this->_wData['x'] - $this->getPaddingX(); | |
} | |
/** | |
* Returns boolean value determining if the orientation asked for is | |
* an accurate orientation. | |
* | |
* @return boolean | |
*/ | |
function isTop() { | |
return strpos(strtolower($this->top),'top') !== false; | |
} | |
function isYCenter() { | |
return strpos(strtolower($this->top),'center') !== false; | |
} | |
function isBottom() { | |
return strpos(strtolower($this->top),'bottom') !== false; | |
} | |
function isLeft() { | |
return strpos(strtolower($this->left),'left') !== false; | |
} | |
function isXCenter() { | |
return strpos(strtolower($this->left),'center') !== false; | |
} | |
function isRight() { | |
return strpos(strtolower($this->left),'right') !== false; | |
} | |
/** | |
* Returns the y padding integer | |
* | |
*/ | |
function getPaddingY() | |
{ | |
if (is_array($this->padding)) | |
{ | |
return $this->padding['y']; | |
} | |
return $this->padding; | |
} | |
/** | |
* Returns the x padding integer | |
* | |
*/ | |
function getPaddingX() | |
{ | |
if (is_array($this->padding)) | |
{ | |
return $this->padding['x']; | |
} | |
return $this->padding; | |
} | |
/** | |
* Sets the padding | |
* | |
*/ | |
function setPadding( $value = NULL ) | |
{ | |
if ($value === NULL) return false; | |
return $this->padding = $value; | |
} | |
/** | |
* Sets the top and left orientation | |
* | |
*/ | |
function setOrientation( $value = NULL ) | |
{ | |
if ($value === NULL) return false; | |
// initializing | |
$this->orientation = $value; | |
$parts = explode(' ', $this->orientation); | |
if (isset($parts[0])) { | |
$this->setTop( $parts[0] ); | |
} | |
if (isset($parts[1])) { | |
$this->setLeft( $parts[1] ); | |
} | |
} | |
/** | |
* Sets the orientation from the top | |
* | |
*/ | |
function setTop( $value ) | |
{ | |
return $this->top = $value; | |
} | |
/** | |
* Sets the orientation from the left | |
* | |
*/ | |
function setLeft( $value ) | |
{ | |
return $this->left = $value; | |
} | |
/** | |
* Sets the primary image and processes it | |
* | |
* @param string $value | |
*/ | |
function setWatermark( $value = NULL ) | |
{ | |
if ($value === NULL) return false; | |
//get the real path | |
$value = str_replace(site_url(), ABSPATH, $value); | |
//remember image | |
$this->watermark = $value; | |
//process this image | |
if (!$this->_wData = $this->getImageData( $this->watermark )) { | |
trigger_error(__CLASS__.": image is not a valid resource ($this->watermark)"); | |
} | |
} | |
/** | |
* Sets the primary image and processes it | |
* | |
* @param string $value | |
*/ | |
function setPrimary( $value = NULL ) | |
{ | |
if ($value === NULL) return false; | |
//get the real path | |
$value = str_replace(site_url(), ABSPATH, $value); | |
//remember image | |
$this->primary = $value; | |
//process this image | |
if (!$this->_pData = $this->getImageData( $this->primary )) { | |
trigger_error(__CLASS__.": image is not a valid resource ($this->primary)"); | |
} | |
} | |
/** | |
* Extends the canvas size of the image | |
* | |
*/ | |
function canvassize() | |
{ | |
if (!$this->extendcanvas) return false; | |
$extend = $this->_wData['y'] + $this->padding + 2; | |
// resizing the canvas | |
$blackcanvas = imagecreatetruecolor($this->_pData['x'], $this->_pData['y'] + $extend ); | |
imagecopyresampled( | |
$blackcanvas, // Destination image link resource. | |
$this->_pData['img'], // Source image link resource. | |
0, // x-coordinate of destination point. | |
0, // y-coordinate of destination point. | |
0, // x-coordinate of source point. | |
0, // y-coordinate of source point. | |
$this->_pData['x'], // Destination width. | |
$this->_pData['y'], // Destination height. | |
$this->_pData['x'], // Source width. | |
$this->_pData['y'] // Source height. | |
); | |
$this->_pData['y'] = $this->_pData['y'] + $extend; | |
$this->_pData['img'] = $blackcanvas; | |
} | |
/** | |
* Creates the horizontal background line | |
* | |
*/ | |
function imageline() | |
{ | |
if (!$this->horizontalline) return false; | |
//initializing | |
$y = ceil($this->getDestinationY() + ($this->_wData['y'] /2)); | |
$im = imagecreatetruecolor ( 140, 140 ); | |
// creating the color | |
$color = imagecolorallocate($im, 255, 255, 255); | |
// merging the line with the primary image | |
$this->imagelinethick( | |
$this->_pData['img'] | |
,0 | |
,$y | |
,$this->_pData['x'] | |
,$y | |
,$color | |
,$this->_wData['y'] + $this->padding + 2 | |
); | |
return true; | |
} | |
/** | |
* This way it works well only for orthogonal lines imagesetthickness($image, $thick); | |
* return imageline($image, $x1, $y1, $x2, $y2, $color); | |
* | |
* @param $image | |
* @param $x1 | |
* @param $y1 | |
* @param $x2 | |
* @param $y2 | |
* @param $color | |
* @param $thick | |
*/ | |
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1) | |
{ | |
if ($thick == 1) | |
return imageline($image, $x1, $y1, $x2, $y2, $color); | |
$t = $thick / 2 - 0.5; | |
if ($x1 == $x2 || $y1 == $y2) | |
return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color); | |
$k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q | |
$a = $t / sqrt(1 + pow($k, 2)); | |
$points = array( | |
round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a), | |
round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a), | |
round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a), | |
round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a), | |
); | |
imagefilledpolygon($image, $points, 4, $color); | |
return imagepolygon($image, $points, 4, $color); | |
} | |
/** | |
* Method to bind an associative array or object to the JTable instance.This | |
* method only binds properties that are publicly accessible and optionally | |
* takes an array of properties to ignore when binding. | |
* | |
* @param mixed $src An associative array or object to bind to the JTable instance. | |
* @param mixed $ignore An optional array or space separated list of properties to ignore while binding. | |
* | |
* @return boolean True on success. | |
* | |
* @link http://docs.joomla.org/JTable/bind | |
* @since 11.1 | |
*/ | |
public function bind($src, $ignore = array()) | |
{ | |
// If the source value is not an array or object return false. | |
if (!is_object($src) && !is_array($src)) | |
{ | |
trigger_error('Bind failed as the provided source is not an array.'); | |
return false; | |
} | |
// If the source value is an object, get its accessible properties. | |
if (is_object($src)) | |
{ | |
$src = get_object_vars($src); | |
} | |
// If the ignore value is a string, explode it over spaces. | |
if (!is_array($ignore)) | |
{ | |
$ignore = explode(' ', $ignore); | |
} | |
// Bind the source value, excluding the ignored fields. | |
foreach ($this->getProperties() as $k => $v) | |
{ | |
// Only process fields not in the ignore array. | |
if (!in_array($k, $ignore)) | |
{ | |
if (isset($src[$k])) | |
{ | |
$this->$k = $src[$k]; | |
} | |
} | |
} | |
return true; | |
} | |
/** | |
* Set the object properties based on a named array/hash. | |
* | |
* @param mixed $properties Either an associative array or another object. | |
* | |
* @return boolean | |
* | |
* @since 11.1 | |
* | |
* @see set() | |
*/ | |
public function setProperties($properties) | |
{ | |
if (is_array($properties) || is_object($properties)) | |
{ | |
foreach ((array) $properties as $k => $v) | |
{ | |
// Use the set function which might be overridden. | |
$this->set($k, $v); | |
} | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Modifies a property of the object, creating it if it does not already exist. | |
* | |
* @param string $property The name of the property. | |
* @param mixed $value The value of the property to set. | |
* | |
* @return mixed Previous value of the property. | |
* | |
* @since 11.1 | |
*/ | |
public function set($property, $value = null) | |
{ | |
$_property = 'set'.str_replace(' ', '', ucwords(str_replace('_', ' ', $property))); | |
if (method_exists($this, $_property)) { | |
return $this->$_property($value); | |
} | |
$previous = isset($this->$property) ? $this->$property : null; | |
$this->$property = $value; | |
return $previous; | |
} | |
/** | |
* Returns an associative array of object properties. | |
* | |
* @param boolean $public If true, returns only the public properties. | |
* | |
* @return array | |
* | |
* @see get() | |
*/ | |
public function getProperties($public = true) | |
{ | |
$vars = get_object_vars($this); | |
if ($public) | |
{ | |
foreach ($vars as $key => $value) | |
{ | |
if ('_' == substr($key, 0, 1)) | |
{ | |
unset($vars[$key]); | |
} | |
} | |
} | |
return $vars; | |
} | |
/** | |
* contains the current instance of this class | |
* | |
* @var object | |
*/ | |
static $_instances = null; | |
/** | |
* Method is called when we need to instantiate this class | |
* | |
* @param array $options | |
*/ | |
public static function getInstance( $primary, $options = array() ) | |
{ | |
if (!isset(self::$_instances[$primary])) | |
{ | |
$options['primary'] = $primary; | |
$class = get_class(); | |
self::$_instances[$primary] =& new $class($options); | |
} | |
return self::$_instances[$primary]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment